mybatis-plus部分插件用法

记录一些mybatisplus的插件用法。

0.准备工作
0-1.新建项目及数据库(略)

0-2.编写各种entity、service(懒人必备自动生成代码)

mybatis-plus-generator

1.乐观锁
1-1.基本概念

乐观锁:假设数据一般情况下不会发生冲突,在实际事务提交时才去判断是否有数据冲突,若检测发生了冲突,本次操作失败。
悲观锁:假设数据一定会发生冲突,在事务进行前先把数据加上锁,待完成数据更新后再释放锁供其他线程使用。

乐观锁的实现方式之一就是增加一个版本字段version,在需要对此记录进行更新时取出oldVersion,完成事务后提交时带上判断当前version是否与之前的version一致,若已发生改变本次操作失效,即 set version = newVersion where version = oldVersion ;

1-2.配置乐观锁插件

创建MybatisPlusConfig配置类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration
@MapperScan("com.lizxing.mybatisplusdemo.mapper")
public class MybatisPlusConfig {

/**
* 乐观锁插件
* @return
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}

}
1-3.实体类增加注解@version
1
2
3
4
5
/**
* 版本号
*/
@Version
private Integer version;
1-4.测试更新

先开启一下控制台sql打印:

1
2
3
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

编写测试方法:

1
2
3
4
5
6
@Test
void testOptimisticLockerInnerInterceptor(){
User user = userMapper.selectById(1);
user.setName("aaa");
userMapper.updateById(user);
}

执行看sql执行过程:

发现确定带上了version进行判断。

若在更新前打个断点,手动去数据库把此条记录的version设高一点,在继续执行更新操作:

乐观锁生效。

2.逻辑删除

逻辑删除即标记某记录为删除状态,而不是直接把delete掉此记录。

数据库先增加逻辑删除字段:

1
2
3
-- 增加逻辑删除字段
ALTER TABLE `test`.`user`
ADD COLUMN `deleted` int(2) NOT NULL DEFAULT 0 COMMENT '逻辑删除(1:已删除 2:未删除)'
2-1.配置逻辑删除插件

配置文件:

1
2
3
4
5
6
mybatis-plus:
global-config:
db-config:
logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
2-2.实体类增加注解@TableLogic
1
2
3
4
5
/**
* 逻辑删除
*/
@TableLogic
private Integer deleted;
2-3.测试删除
1
2
3
4
5
6
7
8
@Test
void testLogicDelete(){
User user = new User();
user.setId(6);
user.setName("test");
userMapper.insert(user);
userMapper.deleteById(user);
}

sql执行过程:

删除操作不再直接执行delete语句,而是使用update把逻辑删除字段变为1。

执行查询时,也会自动加上判断是否已逻辑删除:

逻辑删除生效。

3.自动填充

举时间填充的例子。

【强制】表必备三字段:id, gmt_create, gmt_modified。
说明:其中 id必为主键,类型为 unsigned bigint、单表时自增、步长为 1。gmt_create,gmt_modified的类型均为 date_time类型,前者现在时表示主动创建,后者过去分词表示被动更新。
————————————————
取自阿里数据库设计规范。

3-1.数据库增加两个记录时间的字段
1
2
3
4
-- 增加记录数据创建时间和更新时间
ALTER TABLE `test`.`user`
ADD COLUMN `create_time` datetime(0) NULL COMMENT '创建时间' AFTER `deleted`,
ADD COLUMN `update_time` datetime(0) NULL COMMENT '更新时间' AFTER `create_time`;
3-2.实体类增加对应字段和注解
1
2
3
4
5
6
7
8
9
10
11
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;

/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
3-3.自定义实现类MyMetaObjectHandler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
// 或者
this.strictUpdateFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class); // 起始版本 3.3.3(推荐)
// 或者
this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)
}

@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐)
// 或者
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class); // 起始版本 3.3.3(推荐)
// 或者
this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)
}
}

按道理只需要期中一个,但这里面对每个版本好像都不一样,各种BUG什么的,反正我测试的时候这不生效那不生效的,所以直接三个都写上。

3-4.测试方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
void testAutoFillInsert(){
User user = new User();
user.setId(7);
user.setName("testAutoFillInsert");
userMapper.insert(user);
}

@Test
void testAutoFillUpdate(){
User user = new User();
user.setId(7);
user.setName("testAutoFillUpdate");
userMapper.updateById(user);
}

执行新增时,create_time被自动填充;执行更新时,update_time被自动填充。

不过,如果仅用作时间的填充,这个功能好像没啥用,直接在设置数据库字段时加上自动填充就好了,没必要使用mybatis-plus做这一步:

1
2
3
4
-- 增加记录数据创建时间和更新时间(数据库自动填充)
ALTER TABLE `test`.`user`
ADD COLUMN `create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' AFTER `deleted`,
ADD COLUMN `update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间' AFTER `create_time`;

完事。

未完待续。。。。。。

源码地址:mybatisplus-demo