MyBatis-Plus简介
官网地址https://mybatis.plus/
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
MyBatis-Plus实现CRUD
CRUD
代码仓库地址https://gitee.com/czshh0628/springboot2020/tree/master/spring-boot-mybatisplus-demo
主键策略
MyBatis-Plus默认的主键策略是:ASSIGN_ID (使用了雪花算法)
@TableId(type = IdType.ASSIGN_ID)
private String id;
雪花算法:分布式ID生成器
雪花算法是由Twitter公布的分布式主键生成算法,它能够保证不同表的主键的不重复性,以及相同表的主键的有序性。
核心思想
长度共64bit(一个long型)。
首先是一个符号位,1bit标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0。
41bit时间截(毫秒级),存储的是时间截的差值(当前时间截 - 开始时间截),结果约等于69.73年。10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID,可以部署在1024个节点)。12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID)。
优点:整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞,并且效率较高。
AUTO 自增策略
需要在创建数据表的时候设置主键自增
@TableId(type = IdType.AUTO)
private Long id;
要想影响所有实体的配置,可以设置全局主键配置
#全局设置主键生成策略
mybatis-plus.global-config.db-config.id-type=auto
MyBatis-Plus自动填充
需求
项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。这个时候可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作
标记需要自动填充的字段
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
实现MetaObjectHandler接口
如果自动填充类型是Date那就Date.class和new Date()
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("----insertFill----");
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("----updateFill----");
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}
MyBatis-Plus乐观锁
场景
当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新
原理
取出记录时,获取当前version,更新时,带上这个version,执行更新时, set version = newVersion where version = oldVersion如果version不对,就更新失败
实现流程:
添加乐观锁插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
// 配置乐观锁
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mybatisPlusInterceptor;
}
映射乐观锁字段
- 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
- 仅支持
updateById(id)
与update(entity, wrapper)
方法
@Version
private Integer version;
测试乐观锁
需要先查再修改,否则乐观锁会失效
@GetMapping("update")
public R update() {
User user = userService.getById(1390959068720939009L);
user.setName("张三");
userService.updateById(user);
return R.ok();
}
MyBatis-Plus分页
添加分页插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
// 配置分页
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return mybatisPlusInterceptor;
}
测试分页
@GetMapping("page/{current}/{limit}")
public R page(@PathVariable("current") Long current, @PathVariable("limit") Long limit) {
Page<User> page = new Page<>(current, limit);
userService.page(page, null);
List<User> userList = page.getRecords();
long total = page.getTotal();
return R.ok().data("data", userList).data("total", total);
}
MyBatis-Plus物理&逻辑删除
物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除数据
逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录
使用场景
可以进行数据恢复,有关联数据,不便删除
实现流程:
配置文件添加逻辑删除相关配置
# 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
mybatis-plus.global-config.db-config.logic-delete-field=deleted
# 逻辑已删除值(默认为 1)
mybatis-plus.global-config.db-config.logic-delete-value=1
# 逻辑未删除值(默认为 0)
mybatis-plus.global-config.db-config.logic-not-delete-value=0
映射逻辑删除字段
@TableLogic
@TableField(fill = FieldFill.INSERT)
private Integer deleted;
测试逻辑删除
@GetMapping("delete/{id}")
public R delete(@PathVariable("id") Long id) {
userService.removeById(id);
return R.ok();
}