如何在Spring?Boot中使用MyBatis訪問數據庫
MyBatis,這個對各位使用Java開發(fā)的開發(fā)者來說還是蠻重要的,我相信諸位在企業(yè)開發(fā)項目的時候,大多數采用的是Mybatis。使用MyBatis幫助我們解決各種問題,實際上這篇文章,基本上默認為可以跳過的一篇,但是為了Spring Boot的系列,我還是寫了這篇文章。
MyBatis
作為一個在Hibernate之后出現的持久層框架,因為他支持自定義SQL,存儲過程以及高級映射,MyBatis免除了幾乎所有的JDBC代碼,以及設置參數和獲取結果集的工作。MyBatis可以通過簡單的XML或者注解來配置和映射原始類型,接口,和Java POJO為數據庫中記錄。
MyBatis官網: https://mybatis.org/mybatis-3/zh/index.html
引入依賴
<!--MyBatis依賴-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.oracle.ojdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>19.3.0.0</version>
<scope>compile</scope>
</dependency>這里說明一下,MyBatis的版本和Java JDK和Spring Boot的版本是有要求的:2.1.x版本適用于:MyBatis 3.5+、Java 8+、Spring Boot 2.1+2.0.x版本適用于:MyBatis 3.5+、Java 8+、Spring Boot 2.0/2.11.3.x版本適用于:MyBatis 3.4+、Java 6+、Spring Boot 1.5
配置Application文件
接下來,我們配置Spring Boot的自帶的application配置文件:
# MySQL #spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC #spring.datasource.username=root #spring.datasource.password=123456 #spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver server.port=1001 # Oracle spring.datasource.url=jdbc:oracle:thin:@localhost:1521/orcl spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
這是我的Oracle表結構:

MySQL表結構:
CREATE TABLE `User` ( `id` bigint NOT NULL AUTO_INCREMENT, `name` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL, `age` int DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
接下來創(chuàng)建User表的映射對象,也是我們通用的實體類對象:
public class User {
private Long id;
private String name;
private Integer age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public User() {
}
}在有了實體類對象,并且和數據庫的字段一一對應后,就可以在接口紅定義相關對數據庫表的操作了,這里舉例,一個是查詢,一個是插入,用于后續(xù)單元測試的驗證。
@Mapper
public interface UserMapper {
@Select("SELECT * FROM USER WHERE NAME = #{name}")
User findByName(@Param("name") String name);
@Insert("INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})")
int insert(@Param("name") String name, @Param("age") Integer age);
}接下來創(chuàng)建一個單元測試類,插入一條數據,然后利用這條數據的相關屬性進行查詢,并且判斷相關屬性是否滿足。
注意,測試結束后,對數據進行回滾操作,保證單元測試每次運行的數據環(huán)境獨立。
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class ApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
@Rollback
public void test() throws Exception {
userMapper.insert("AAA", 20);
User u = userMapper.findByName("AAA");
Assert.assertEquals(20, u.getAge().intValue());
}
}對于注解配置進行說明介紹
@Mapper:用于標注Mapper接口,表示該接口是MyBatis的Mapper映射接口。在Spring Boot項目中,可以使用@MapperScan注解掃描指定包下的Mapper接口,并將其注冊為Bean。
@Select:用于標注查詢語句,指定SQL語句或調用Mapper XML文件中的對應SQL語句。可以通過value屬性指定SQL語句,也可以通過provider屬性指定動態(tài)SQL提供者類。
@Insert、@Update、@Delete:分別用于標注插入、更新和刪除語句,使用方式與@Select類似。
@Result、@Results:用于標注結果集映射關系。@Result用于標注單個字段或屬性與結果集列的映射關系,@Results用于標注多個@Result。
@Param:用于標注方法參數,指定參數在SQL語句中的名稱。在SQL語句中可以通過#{參數名}的方式引用該參數。
@Options:用于配置一些選項,例如設置主鍵生成策略、返回自增主鍵等。
@ResultMap:用于標注結果集映射配置的ID,可以在其他地方通過@ResultMap引用該結果集映射。
@One、@Many:用于標注一對一和一對多的關聯(lián)關系。
@CacheNamespace:用于開啟二級緩存,將Mapper的查詢結果緩存到內存中,提高查詢性能。
| 注解 | 使用對象 | 相對應的 XML | 描述 |
|---|---|---|---|
@Insert @Update @Delete @Select | 方法 | <insert><update><delete><select> | 這四個注解分別代表將會被執(zhí)行的 SQL 語句。它們用字符串數組(或單個字符串)作為參數。如果傳遞的是字符串數組,字符串之間先會被填充一個空格再連接成單個完整的字符串。這有效避免了以 Java 代碼構建 SQL 語句時的“丟失空格”的問題。然而,你也可以提前手動連接好字符串。屬性有:value,填入的值是用來組成單個 SQL 語句的字符串數組。 |
@Options | 方法 | 映射語句的屬性 | 這個注解提供訪問大范圍的交換和配置選項的入口,它們通常在映射語句上作為屬性出現。Options 注解提供了通俗易懂的方式來訪問它們,而不是讓每條語句注解變復雜。屬性有:useCache=true, flushCache=FlushCachePolicy.DEFAULT, resultSetType=FORWARD_ONLY, statementType=PREPARED, fetchSize=-1, timeout=-1, useGeneratedKeys=false, keyProperty="id", keyColumn="", resultSets=""。值得一提的是, Java 注解無法指定 null 值。因此,一旦你使用了 Options 注解,你的語句就會被上述屬性的默認值所影響。要注意避免默認值帶來的預期以外的行為。注意: keyColumn 屬性只在某些數據庫中有效(如 Oracle、PostgreSQL等)。請在插入語句一節(jié)查看更多關于 keyColumn 和 keyProperty 兩者的有效值詳情。 |
@MapKey | 方法 | – | 這是一個用在返回值為 Map 的方法上的注解。它能夠將存放對象的 List 轉化為 key 值為對象的某一屬性的 Map。屬性有: value,填入的是對象的屬性名,作為 Map 的 key 值。 |
@SelectKey | 方法 | <selectKey> | 這個注解的功能與 <selectKey> 標簽完全一致,用在已經被 @Insert 或 @InsertProvider 或 @Update 或 @UpdateProvider 注解了的方法上。若在未被上述四個注解的方法上作 @SelectKey 注解則視為無效。如果你指定了 @SelectKey 注解,那么 MyBatis 就會忽略掉由 @Options 注解所設置的生成主鍵或設置(configuration)屬性。屬性有:statement 填入將會被執(zhí)行的 SQL 字符串數組,keyProperty 填入將會被更新的參數對象的屬性的值,before 填入 true 或 false 以指明 SQL 語句應被在插入語句的之前還是之后執(zhí)行。resultType 填入 keyProperty 的 Java 類型和用 Statement、 PreparedStatement 和 CallableStatement 中的 STATEMENT、 PREPARED 或 CALLABLE 中任一值填入 statementType。默認值是 PREPARED。 |
@Param | 參數 | N/A | 如果你的映射方法的形參有多個,這個注解使用在映射方法的參數上就能為它們取自定義名字。若不給出自定義名字,多參數(不包括 RowBounds 參數)則先以 “param” 作前綴,再加上它們的參數位置作為參數別名。例如 #{param1}, #{param2},這個是默認值。如果注解是 @Param(“person”),那么參數就會被命名為 #{person}。 |
@InsertProvider @UpdateProvider @DeleteProvider @SelectProvider | 方法 | <insert> <update> <delete> <select> | 允許構建動態(tài) SQL。這些備選的 SQL 注解允許你指定類名和返回在運行時執(zhí)行的 SQL 語句的方法。(自從MyBatis 3.4.6開始,你可以用 CharSequence 代替 String 來返回類型返回值了。)當執(zhí)行映射語句的時候,MyBatis 會實例化類并執(zhí)行方法,類和方法就是填入了注解的值。你可以把已經傳遞給映射方法了的對象作為參數,“Mapper interface type” 和 “Mapper method” 會經過 ProviderContext (僅在MyBatis 3.4.5及以上支持)作為參數值。(MyBatis 3.4及以上的版本,支持多參數傳入)屬性有: type, method。type 屬性需填入類。method 需填入該類定義了的方法名。注意 接下來的小節(jié)將會討論類,能幫助你更輕松地構建動態(tài) SQL。 |
這里就圍繞@Param,Map聊聊。
@Param
我們在實際開發(fā)過程中,如果將SQL語句嵌套在接口的時候,我們經常使用的方式就是這種:
@Insert("INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})")
int insert(@Param("name") String name, @Param("age") Integer age);這種方式,我們都很少理解,@Param中定義的name對應了SQL中的#{name},age對應了SQL中的#{age}。
Map
除了以@Param注入,我們也可以通過Map<String,Object> 對象作為傳遞參數的容器:
@Insert("INSERT INTO USER(NAME, AGE) VALUES(#{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER})")
int insertByMap(Map<String, Object> map);得到如上代碼,那么我們應該如何注入呢?
Map<String, Object> map = new HashMap<>();
map.put("name", "CCC");
map.put("age", 40);
userMapper.insertByMap(map);如上,我們通過對map中填入同名的內容就可以實現了。
使用對象注入
除去Map方式注入值外,我們也可以直接java對象直接作為查詢條件的傳參,比如我們可以直接使用User對象:
@Insert("INSERT INTO USER(NAME, AGE) VALUES(#{name}, #{age})")
int insertByUser(User user);利用MyBatis實現增刪改查
MyBatis針對不同的數據庫操作,分別提供了不同的注解進行配置:
public interface UserMapper {
@Select("SELECT * FROM user WHERE name = #{name}")
User findByName(@Param("name") String name);
@Insert("INSERT INTO user(name, age) VALUES(#{name}, #{age})")
int insert(@Param("name") String name, @Param("age") Integer age);
@Update("UPDATE user SET age=#{age} WHERE name=#{name}")
void update(User user);
@Delete("DELETE FROM user WHERE id =#{id}")
void delete(Long id);
}之后我們可以利用創(chuàng)建一個Test測試類,來實現我們的功能是否正常實現:
@Transactional
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
@Rollback
public void testUserMapper() throws Exception {
// insert一條數據,并select出來驗證
userMapper.insert("AAA", 20);
User u = userMapper.findByName("AAA");
Assert.assertEquals(20, u.getAge().intValue());
// update一條數據,并select出來驗證
u.setAge(30);
userMapper.update(u);
u = userMapper.findByName("AAA");
Assert.assertEquals(30, u.getAge().intValue());
// 刪除這條數據,并select驗證
userMapper.delete(u.getId());
u = userMapper.findByName("AAA");
Assert.assertEquals(null, u);
}
}返回結果綁定
對于增、刪、改操作相對的數據也就變化較小,但是對于查我們就需要考慮的比較多了,怎么查,多表查,子查,并且查詢的結果也不在是我們經常碰到的實體類對象了,往往需要返回一個與數據庫實體不同的包裝類,那么對于這樣的情況,我們可以通過@Result和@Result注解進行綁定。
@Results({
@Result(property = "name", column = "name"),
@Result(property = "age", column = "age")
})
@Select("SELECT name, age FROM user")
List<User> findAll();@Result中的property屬性對應User對象中的成員名,column對應SELECT出的字段名。在該配置中故意沒有查出id屬性,只對User對應中的name和age對象做了映射配置,這樣可以通過下面的單元測試來驗證查出的id為null,而其他屬性不為null:
@Test
@Rollback
public void testUserMapper() throws Exception {
List<User> userList = userMapper.findAll();
for(User user : userList) {
Assert.assertEquals(null, user.getId());
Assert.assertNotEquals(null, user.getName());
}
}到此這篇關于如何在Spring Boot中使用MyBatis訪問數據庫的文章就介紹到這了,更多相關Spring Boot使用MyBatis訪問數據庫內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
簡單了解JAVA public class與class區(qū)別
這篇文章主要介紹了簡單了解JAVA public class與class區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-03-03
IntelliJ IDEA 設置代碼提示或自動補全的快捷鍵功能
這篇文章主要介紹了IntelliJ IDEA 設置代碼提示或自動補全的快捷鍵功能,需要的朋友可以參考下2018-03-03
一文搞懂Mybatis中Mapper配置文件獲取參數的五種方式
這篇文章主要介紹了Mybatis中Mapper配置文件獲取參數的五種方式,文中通過代碼示例講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下2024-03-03
使用Java將DOCX文檔解析為Markdown文檔的代碼實現
在現代文檔處理中,Markdown(MD)因其簡潔的語法和良好的可讀性,逐漸成為開發(fā)者、技術寫作者和內容創(chuàng)作者的首選格式,然而,許多文檔仍然以Microsoft Word的DOCX格式保存,本文將介紹如何使用Java和相關庫將DOCX文檔解析為Markdown文檔,需要的朋友可以參考下2025-04-04

