记录一些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 { @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;
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 ()) ; this .strictUpdateFill(metaObject, "createTime" , LocalDateTime::now, LocalDateTime.class ) ; this .fillStrategy(metaObject, "createTime" , LocalDateTime.now()); } @Override public void updateFill (MetaObject metaObject) { this .strictUpdateFill(metaObject, "updateTime" , LocalDateTime.class , LocalDateTime .now ()) ; this .strictUpdateFill(metaObject, "updateTime" , LocalDateTime::now, LocalDateTime.class ) ; this .fillStrategy(metaObject, "updateTime" , LocalDateTime.now()); } }
按道理只需要期中一个,但这里面对每个版本好像都不一样,各种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