芋道 Spring Boot MyBatis 入門(四)之 tkmybatis
- 2019 年 11 月 23 日
- 筆記
摘要: 原創出處 http://www.iocoder.cn/Spring-Boot/MyBatis/ 「芋道源碼」歡迎轉載,保留摘要,謝謝!
- 1. 概述
- 2. MyBatis + XML
- 2.1 引入依賴
- 2.2 Application
- 2.3 應用配置文件
- 2.4 MyBatis 配置文件
- 2.5 UserDO
- 2.6 UserMapper
- 2.7 簡單測試
- 3. MyBatis + 註解
- 3.1 差異部分
- 3.2 UserMapper
- 3.3 簡單測試
- 4. MyBatis-Plus
- 4.1 引入依賴
- 4.2 Application
- 4.3 應用配置文件
- 4.4 UserDO
- 4.5 UserMapper
- 4.6 簡單測試
- 5. tkmybatis
- 5.1 引入依賴
- 5.2 Application
- 5.3 應用配置文件
- 5.4 MyBatis 配置文件
- 5.5 UserDO
- 5.6 UserMapper
- 5.7 簡單測試
- 666. 彩蛋
5. tkmybatis
關於 tkmybatis 的介紹,直接到官網,艿艿就不多嗶嗶,嘿嘿。
需要注意的是,tkmybatis 對自己的定位是 mybatis 的工具的意思,那麼 tk 猜測是 toolkit 的縮寫。也因此,tkmybatis 是多個開源項目組合起來的:
- Mapper :提供通用的 MyBatis Mapper 。
- Mybatis-PageHelper :提供 MyBatis 分頁插件。
本小節,我們會使用 tkmybatis 實現我們在 「3. MyBatis-Plus」 的各種 CRUD 操作。
艿艿:說實在的,還是喜歡 MyBatis-Plus 。一站式,文檔也更加齊全和易懂。
5.1 引入依賴
在 pom.xml 文件中,引入相關依賴。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>lab-12-mybatis-tk</artifactId> <dependencies> <!-- 實現對資料庫連接池的自動化配置 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <!-- 本示例,我們使用 MySQL --> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.48</version> </dependency> <!-- 實現對 MyBatis 的自動化配置 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.1</version> </dependency> <!-- 實現對 Mapper 的自動化配置--> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>2.1.5</version> </dependency> <!-- 實現對 PageHelper 的自動化配置--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.5</version> <exclusions> <exclusion> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </exclusion> </exclusions> </dependency> <!-- 方便等會寫單元測試 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> </project>
- 引入
mybatis-spring-boot-starter依賴,自動化配置 MyBatis 。 - 引入
mapper-spring-boot-starter依賴,自動化配置 Mapper 。 - 引入
pagehelper-spring-boot-starter依賴,自動化配置 PageHelper 。
5.2 Application
創建 Application.java 類,配置 @MapperScan 註解,掃描對應 Mapper 介面所在的包路徑。程式碼如下:
// Application.java @SpringBootApplication @MapperScan(basePackages = "cn.iocoder.springboot.lab12.mybatis.mapper") // 注意,要換成 tk 提供的 @MapperScan 註解 public class Application { }- 注意,整列使用的是 tkmybatis 提供的
tk.mybatis.spring.annotation.@MapperScan註解。
5.3 應用配置文件
在 resources 目錄下,創建 application.yaml 配置文件。配置如下:
spring: # datasource 數據源配置內容 datasource: url: jdbc:mysql://47.112.193.81:3306/testb5f4?useSSL=false&useUnicode=true&characterEncoding=UTF-8 driver-class-name: com.mysql.jdbc.Driver username: testb5f4 password: F4df4db0ed86@11 # mybatis 配置內容 mybatis: config-location: classpath:mybatis-config.xml # 配置 MyBatis 配置文件路徑 mapper-locations: classpath:mapper/*.xml # 配置 Mapper XML 地址 type-aliases-package: cn.iocoder.springboot.lab12.mybatis.dataobject # 配置資料庫實體包路徑 # mapper 配置內容 mapper: mappers: cn.iocoder.springboot.lab12.mybatis.util.BaseMapper # 設置基礎 Mapper 介面 not-empty: true # 在 INSERT 和 UPDATE 操作時,是否會判斷欄位是否為空。即 <if test='xxx != null' /> identity: MYSQL # PageHelper 配置內容 # 具體的參數作用,看 https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md pagehelper: helperDialect: mysql # 分頁插件會自動檢測當前的資料庫鏈接,自動選擇合適的分頁方式。 你可以配置helperDialect屬性來指定分頁插件使用哪種方言。 reasonable: true # 分頁合理化參數,默認值為false。當該參數設置為 true 時,pageNum<=0 時會查詢第一頁, pageNum>pages(超過總數時),會查詢最後一頁。默認false 時,直接根據參數進行查詢。 supportMethodsArguments: true # 支援通過 Mapper 介面參數來傳遞分頁參數,默認值false,分頁插件會從查詢方法的參數值中,自動根據上面 params 配置的欄位中取值,查找到合適的值時就會自動分頁。 使用方法可以參考測試程式碼中的 com.github.pagehelper.test.basic 包下的 ArgumentsMapTest 和 ArgumentsObjTest。 # logging logging: level: # dao 開啟 debug 模式 mybatis 輸入 sql cn: iocoder: springboot: lab12: mybatis: mapper: debug
- 一共有
mybatis、mapper、pagehelper三大塊配置項。相比 MyBatis-Plus 略微複雜一些。具體每個配置項的作用,胖友看下注釋。 - 有一點要注意,`cn.iocoder.springboot.lab12.mybatis.util.BaseMapper` 介面,需要我們自己定義,去繼承
tk.mybatis.mapper.common.Mapper和tk.mybatis.mapper.common.MySqlMapper介面。
5.4 MyBatis 配置文件
在 resources 目錄下,創建 mybatis-config.xml 配置文件。配置如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <!-- 使用駝峰命名法轉換欄位。 --> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <typeAliases> <typeAlias alias="Integer" type="java.lang.Integer"/> <typeAlias alias="Long" type="java.lang.Long"/> <typeAlias alias="HashMap" type="java.util.HashMap"/> <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap"/> <typeAlias alias="ArrayList" type="java.util.ArrayList"/> <typeAlias alias="LinkedList" type="java.util.LinkedList"/> </typeAliases> </configuration>
- 和 「2.3 MyBatis 配置文件」 一致。
5.5 UserDO
在 cn.iocoder.springboot.lab12.mybatis.dataobject 包路徑下,創建 UserDO.java 類,用戶 DO 。程式碼如下:
// UserDO.java /** * 用戶 DO */ @Table(name = "users") public class UserDO { /** * 用戶編號 */ @Id // 表示該欄位為主鍵 ID @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "JDBC") // strategy 設置使用資料庫主鍵自增策略;generator 設置插入完成後,查詢最後生成的 ID 填充到該屬性中。 private Integer id; /** * 帳號 */ private String username; /** * 密碼(明文) * * ps:生產環境下,千萬不要明文噢 */ private String password; /** * 創建時間 */ private Date createTime; public Integer getId() { return id; } public UserDO setId(Integer id) { this.id = id; return this; } public String getUsername() { return username; } public UserDO setUsername(String username) { this.username = username; return this; } public String getPassword() { return password; } public UserDO setPassword(String password) { this.password = password; return this; } public Date getCreateTime() { return createTime; } public UserDO setCreateTime(Date createTime) { this.createTime = createTime; return this; } }- 因為 Mapper 暫時不支援邏輯刪除功能,所以這裡我們去除了
deleted屬性。Mapper 的開發者,傾向使用者,自己在業務邏輯中實現邏輯刪除。 @Table、@Id、@GeneratedValue註解,使用的是 JPA 提供的註解。如果不知道怎麼引入這三個註解,胖友可以看看 UserDO.java 類。
對應的創建表的 SQL 如下:
CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用戶編號', `username` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '帳號', `password` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密碼', `create_time` datetime DEFAULT NULL COMMENT '創建時間', PRIMARY KEY (`id`), UNIQUE KEY `idx_username` (`username`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
5.6 UserMapper
在 cn.iocoder.springboot.lab12.mybatis.mapper 包路徑下,創建 UserMapper 介面。程式碼如下:
// UserMapper.java @Repository public interface UserMapper extends BaseMapper<UserDO> { // 繼承的是,我們定義的 BaseMapper 介面 default UserDO selectByUsername(@Param("username") String username) { Example example = new Example(UserDO.class); // 創建 Criteria 對象,設置 username 查詢條件 example.createCriteria().andEqualTo("username", username); // 執行查詢 return selectOneByExample(example); } List<UserDO> selectByIds(@Param("ids") Collection<Integer> ids); default List<UserDO> selectListByCreateTime(@Param("createTime") Date createTime) { Example example = new Example(UserDO.class); // 創建 Criteria 對象,設置 create_time 查詢條件 example.createCriteria().andGreaterThan("createTime", createTime); return selectByExample(example); } }- 繼承的介面,是我們自己定義的 `cn.iocoder.springboot.lab12.mybatis.util.BaseMapper` 介面。
- 在 MyBatis-Plus 中,我們使用 QueryWrapper 拼裝動態 SQL 。而在 tkmybatis 中,通過使用它提供的 Example 和 Criteria 類。
- 關於分頁,PageHelper 的使用方式,有點神奇,我們在 「5.6 簡單測試」 來看。
在 resources/mapper 路徑下,創建 UserMapper.xml 配置文件。程式碼如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.iocoder.springboot.lab12.mybatis.mapper.UserMapper"> <sql id="FIELDS"> id, username, password, create_time </sql> <select id="selectByIds" resultType="UserDO"> SELECT <include refid="FIELDS" /> FROM users WHERE id IN <foreach item="id" collection="ids" separator="," open="(" close=")" index=""> #{id} </foreach> </select> </mapper>- 這個沒有差別哈。
5.7 簡單測試
創建 UserMapperTest 測試類,我們來測試一下簡單的 UserMapper 的每個操作。程式碼如下:
// UserMapperTest.java @RunWith(SpringRunner.class) @SpringBootTest(classes = Application.class) public class UserMapperTest { @Autowired private UserMapper userMapper; @Test public void testInsert() { UserDO user = new UserDO().setUsername(UUID.randomUUID().toString()) .setPassword("nicai").setCreateTime(new Date()); userMapper.insert(user); System.out.println(user.getId()); } @Test public void testUpdateById() { UserDO updateUser = new UserDO().setId(1) .setPassword("wobucai"); userMapper.updateByPrimaryKey(updateUser); } @Test public void testDeleteById() { userMapper.deleteByPrimaryKey(2); } @Test public void testSelectById() { userMapper.selectByPrimaryKey(1); } @Test public void testSelectByUsername() { userMapper.selectByUsername("yunai"); } @Test public void testSelectByIds() { List<UserDO> users = userMapper.selectByIds(Arrays.asList(1, 3)); System.out.println("users:" + users.size()); } @Test // 更多使用,可以參考 https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md public void testSelectPageByCreateTime() { // 設置分頁 PageHelper.startPage(1, 10); Date createTime = new Date(2018 - 1990, Calendar.FEBRUARY, 24); // 臨時 Demo ,實際不建議這麼寫 // 執行列表查詢 // PageHelper 會自動發起分頁的數量查詢,設置到 PageHelper 中 List<UserDO> users = userMapper.selectListByCreateTime(createTime); // 實際返回的是 com.github.pagehelper.Page 代理對象 // 轉換成 PageInfo 對象,並輸出分頁 PageInfo<UserDO> page = new PageInfo<>(users); System.out.println(page.getTotal()); } }- 分頁邏輯,在
#testSelectPageByCreateTime()方法中,我們已經進行實現。相比來說,個人不是很喜歡 PageHelper 這種方式。也和朋友聊了下,他們也傾向類似 MyBatis-Plus 提供的分頁方式。
666. 彩蛋
總的來說,個人還是比較推薦在項目中使用 MyBatis-Plus 。也問了好些朋友,目前都處於要麼在使用 MyBatis-Plus ,要麼新項目考慮使用 MyBatis-Plus 。
在之前使用 Spring Data JPA 的過程中,還是比較喜歡可以通過方法名,自動生成對應的 CRUD 操作。所以,就琢磨有沒可能 Spring Data JPA 底層實現,除了使用 Hibernate ,是否有可能使用 MyBatis 呢?於是乎,在 Github 上竟然搜到了 spring-data-jpa-mybatis 項目。有點神奇,感興趣的胖友可以試試。當然,生產上不是很建議哈。
