阅读本文需要 10 分钟,内容从官方手册抽取,都是比较常见的用法,访问官网可以获取最全面的解读 Mybatis-Plus
1. 配置
1.1 引入依赖
使用 IDEA 的 Spring Initializer 可以快速创建一个 Spring Boot 项目,需要 mysql 和 mybatis的驱动
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- mybatis-plus 是第三方框架,Spring Initializer里面搜索不到,需要自行添加 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
1.2 配置 apllication.yml
spring:
# 默认激活开发环境
profiles:
active: dev
# 数据库连接参数
datasource:
# mysql8 的驱动是 com.mysql.cj.jdbc.Driver
driver-class-name: com.mysql.cj.jdbc.Driver
# mysql8 需要增加时区的配置,serverTimezone=GMT%2B8 或者 serverTimezone=Asia/Shanghai
url: jdbc:mysql://192.168.2.31:3306/test?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
username: your username
password: your password
mybatis-plus:
mapper-locations:
# 配置 mapper.xml 位置
classpath: mapper/*.xml
configuration:
# 配置日志 (打印SQL及参数)
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
# 逻辑删除
logic-delete-value: 1
logic-not-delete-value: 0
1.3 Mapper接口
继承 com.baomidou.mybatisplus.core.mapper.BaseMapper 接口就能获取到 CRUD 方法
@Mapper
public interface UserMapper extends BaseMapper<User> {
// 可以添加自己编写的sql
// 配置文件加上 mybatis-plus.mapper-locations.classpath=mapper/*.xml 即可
// 此处不做演示
}
到这里其实可以使用了,但建议增加一个配置类,将 MyBatisPlus 相关配置都放在一起,便于管理
1.4 配置类
/**
* 说明
* 1. @MapperScan 的功能是扫描指定包下面的 Mapper 接口生成代理类
* 2. @Mapper 则是指定具体的接口生成代理类,一般情况都是将接口放到一个包下,所以使用@MapperScan 更为简洁和方便
* 3. 使用 @Autowired 注入 Mapper 接口时,IDEA 会有红色波浪线,可以给 Mapper 接口加上@Repository 消除红色波浪线,但是不加也没有问题
*/
@MapperScan("mapper接口路径")
@EnableTransactionManagement
@Configuration
public class MyBatisPlusConfig {
// 可以添加插件
}
2. 使用
数据库脚本
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '姓名',
`age` int(11) NULL DEFAULT NULL COMMENT '年龄',
`email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱',
`gmt_create` datetime(0) DEFAULT NULL COMMENT '创建时间',
`gmt_modified` datetime(0) DEFAULT NULL COMMENT '修改时间',
`version` int(11) DEFAULT 0 COMMENT '版本号',
`deleted` int(11) DEFAULT 0 COMMENT '逻辑删除标志 0-未删除,1-已删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1342743645248716811 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
INSERT INTO `user` VALUES (1, 'kwhua', 20, '123456@qq.com', '2020-12-29 09:01:16', '2020-12-29 09:01:16', 0, 1);
INSERT INTO `user` VALUES (2, 'Jack', 20, 'test2@baomidou.com', '2020-12-29 09:01:16', '2020-12-29 09:01:16', 0, 0);
INSERT INTO `user` VALUES (3, 'Tom', 28, 'test3@baomidou.com', '2020-12-29 09:01:16', '2020-12-29 09:01:16', 0, 0);
INSERT INTO `user` VALUES (4, 'Sandy', 21, 'test4@baomidou.com', '2020-12-29 09:01:16', '2020-12-29 09:01:16', 0, 0);
INSERT INTO `user` VALUES (5, 'Billie', 24, 'test5@baomidou.com', '2020-12-29 09:01:16', '2020-12-29 09:01:16', 0, 0);
实体类
@Data
public class User {
private Long id;
private String name;
private Integer age;
private String email;
private Date gmtCreate;
private Date gmtModified;
private Integer version;
private Integer deleted;
}
2.1 查询
// 根据id批量查询
userMapper.selectBatchIds(Arrays.asList(1, 2, 3)).forEach(System.out::println);
// 用map组合自定义条件查询
Map<String, Object> map = new HashMap<>();
map.put("name", "kwhua");
map.put("age", 20);
userMapper.selectByMap(map).forEach(System.out::println);
// 使用条件构造器
// 1) WHERE name = ? AND age = ?
QueryWrapper<User> wrapper = new QueryWrapper<>();
User user = new User();
user.setName("kwhua");
user.setAge(20);
wrapper.setEntity(user);
userMapper.selectList(wrapper).forEach(System.out::println);
// 2) WHERE name IS NOT NULL AND email IS NOT NULL AND age >= ?
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.isNotNull("name")
.isNotNull("email")
.ge("age", 18);
userMapper.selectList(wrapper).forEach(System.out::println);
// 3) 模糊查询 WHERE name IS NOT NULL AND email IS NOT NULL AND age >= ? AND name LIKE ?
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("name")
.isNotNull("email")
.ge("age", 18);
wrapper.like("name", "a");
userMapper.selectList(wrapper).forEach(System.out::println);
2.2 新增时指定主键生成策略
使用注解 @TableId 指定主键生成策略
//主键生成策略
// AUTO(0), // 数据库id自增
// NONE(1), // 未设置主键
// INPUT(2), // 手动输入
// ID_WORKER(3), // 默认的方式,全局唯一id
// UUID(4), // 全局唯一id uuid
// ID_WORKER_STR(5); // ID_WORKER 字符串表示法
@TableId(type = IdType.AUTO)
private Long id;
新增时会使用主键生成策略,并且在新增之后注入到实体类
User user = new User();
user.setName("kwhua_mybatis-plus_insertTest");
user.setAge(15);
user.setEmail("310697723@qq.com");
int result = userMapper.insert(user); // 帮我们自动生成id
System.out.println(result); // 受影响的行数
System.out.println(user); // 看到id会自动填充
2.3 自动填充功能
使用注解 @TableField 指定填充策略
// 新增时填充
@TableField(fill = FieldFill.INSERT)
private Date gmtCreate;
// 新增或更新时填充
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified;
3. 插件
3.1 分页插件
在配置类注册 PaginationInterceptor
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
使用分页插件查询
Page<User> page = new Page<>(pageNo, pageSize);
userMapper.selectPage(page, wrapper);
page.getRecords().forEach(System.out::println);
3.2 乐观锁
在配置类注册 OptimisticLockerInterceptor
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
使用注解 @Version
@Version
private Integer version;
更新时的SQL UPDATE user SET xx = xx, version=? WHERE id=? AND version=?
// 1、查询用户信息
User user = userMapper.selectById(1L);
// 2、修改用户信息
user.setName("kwhua");
user.setEmail("123456@qq.com");
// 3、执行更新操作
userMapper.updateById(user);
3.3 逻辑删除
在配置类注册 ISqlInjector
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
使用注解 @TableLogic
//@TableLogic(value = "0", delval = "1")
@TableLogic // 或者从全局配置读取
private Integer deleted;
3.4 SQL执行效率插件
在配置类注册 PerformanceInterceptor
@Bean
@Profile({"dev", "test"})// 设置 dev test 环境开启,保证我们的效率
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
//ms 设置sql执行的最大时间,如果超过了则不执行
performanceInterceptor.setMaxTime(100);
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}