芋道 Spring Boot MyBatis 入门(四)之 tkmybatis
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 的介绍,直接到 http://www.mybatis.tk/ 官网,艿艿就不多哔哔,嘿嘿。
需要注意的是,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 项目。有点神奇,感兴趣的胖友可以试试。当然,生产上不是很建议哈。
更多相关文章
- 芋道 Spring Boot JPA 入门(三)之基于注解查询
- 芋道 Spring Boot MyBatis 入门(二)之 MyBatis + 注解
- SpringBoot 中 @SpringBootApplication注解背后的三体结构探秘
- 面试官:高并发下重启服务,接口调用老是超时,你有什么解决办法?
- 如何实时主动监控你的网站接口是否挂掉并及时报警
- 使用Flask在服务器实现一个API接口。
- MySQL+Flask,在本地实现一个API接口。
- Spring 注解编程之模式注解
- 使用类型注解让 Python 代码更易读