芋道 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 項目。有點神奇,感興趣的胖友可以試試。當然,生產上不是很建議哈。

Tags: