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