前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >芋道 Spring Boot MyBatis 入门(四)之 tkmybatis

芋道 Spring Boot MyBatis 入门(四)之 tkmybatis

作者头像
芋道源码
发布2019-11-23 17:20:02
1.5K0
发布2019-11-23 17:20:02
举报
文章被收录于专栏:芋道源码1024芋道源码1024

摘要: 原创出处 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 文件中,引入相关依赖。

代码语言:javascript
复制
<?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 接口所在的包路径。代码如下:

代码语言:javascript
复制
// 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 配置文件。配置如下:

代码语言:javascript
复制
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
  • 一共有 mybatismapperpagehelper 三大块配置项。相比 MyBatis-Plus 略微复杂一些。具体每个配置项的作用,胖友看下注释。
  • 有一点要注意,`cn.iocoder.springboot.lab12.mybatis.util.BaseMapper` 接口,需要我们自己定义,去继承 tk.mybatis.mapper.common.Mappertk.mybatis.mapper.common.MySqlMapper 接口。

5.4 MyBatis 配置文件

resources 目录下,创建 mybatis-config.xml 配置文件。配置如下:

代码语言:javascript
复制
<?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 。代码如下:

代码语言:javascript
复制
// 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 如下:

代码语言:javascript
复制
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 接口。代码如下:

代码语言:javascript
复制
// 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 配置文件。代码如下:

代码语言:javascript
复制
<?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 的每个操作。代码如下:

代码语言:javascript
复制
// 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 项目。有点神奇,感兴趣的胖友可以试试。当然,生产上不是很建议哈。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 芋道源码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 5. tkmybatis
    • 5.1 引入依赖
      • 5.2 Application
        • 5.3 应用配置文件
          • 5.4 MyBatis 配置文件
            • 5.5 UserDO
              • 5.6 UserMapper
                • 5.7 简单测试
                • 666. 彩蛋
                相关产品与服务
                云数据库 MySQL
                腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档