侧边栏壁纸
  • 累计撰写 57 篇文章
  • 累计创建 23 个标签
  • 累计收到 4 条评论

MybatisPlus从入门到精通-高级篇

cluski
2022-04-09 / 0 评论 / 2 点赞 / 135 阅读 / 3,187 字
温馨提示:
本文最后更新于 2022-04-09,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

MybatisPlus从入门到精通-高级篇

1 自动填充

​ 在实际项目中的表会和我们的orders表一样,有更新时间,创建时间,创建人,更新人等字段。

​ 我们可以使用@TableF1e1dfill属性来设置字段的自动填充。让我们能更方便的更新相关字段。

示例

① 在对应字段上增加注解

​ 使用TableField注解的fill属性来标注哪些字段需要在自动填充,加了注解MP才会在对应的sql中为我们预留字段。而属性值代表我们在什么进行什么操作时需要预留字段。

/**
 * 更新时间
 */
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;

/**
 * 创建时间
 */
@TableField(fill = FieldFill.UPDATE)
private Date createTime;

② 自定义填充处理器MetaObjectHandler

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
        this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
        this.strictInsertFill(metaObject, "del_flag", Integer.class, 0);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
    }
}

③ 测试

ordersMapper.insert(
        new Orders()
                .setPrice(5000)
                .setRemark("none")
                .setUserId(1)
);

ordersMapper.update(
        new Orders().setPrice(6000),
        new LambdaQueryWrapper<Orders>()
                .eq(Orders::getPrice, 5000)
);

2 逻辑删除

​ MP也支持逻删除的处理。我们只需要配置好逻删除的实体字段名,代表删除的字段值和代表未删除的字段
值后即可。

​ 注意:如果3.3.0版本之前还需要在对应的字段上加上@TableLogic注解

① 配置

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: delFlag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

② 实体类字段上加上@TableLogic注解

@TableLogic
private Integer delFlag;

**注意:**只有在使用Service,Mapper中MybatisPlus提供的CRUD方法时,此配置会生效。但是如果是自己定义的Mapper方法时,是不会生效的。

3 乐观锁

​ 并发操作时,我们需要保证对数据的操作不发生冲突。乐观锁就是其中一种方式。乐观锁就是先加上不存在并发
冲突问题,在进行实际数据操作的时候再检查是否冲突。

​ 我们在使用乐观锁时一般在表中增加一个version列。用来记录我们对每个记录操作的版本。每次对某条记录进
行过操作是,对应的版本也需要+1。

​ 然后我们在每次要进行更新操作时,先查询对应数据的version值。在执行更新时,set version=老版本+1
where version=老版本

​ 如果在查询老版本号到更新操作的中间时该刻有其他人更新了这条数据,这样这次更新语句就会更新失败。

​ 这里在更新时对version的操作如果有我们自己做就会显的有点麻烦。所以MP提供了乐观锁插件。

​ 使用后我们就可以非常方便的实现对version的操作。

3.1 使用

① 配置对应插件

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    return interceptor;
}

② 在实体类的字段上加上@Version注解

③ 更新

@Test
public void testVersion() {
    Orders order = ordersMapper.selectById(3);
    System.out.println(order);

    order.setPrice(88);
    ordersMapper.updateById(order);
}

这种情况下我们可以看到执行的sql发生了变化。

==>  Preparing: UPDATE orders SET price=?, remark=?, user_id=?, update_time=?, create_time=?, version=? WHERE id=? AND version=? AND del_flag=0
==> Parameters: 88(Integer), 无(String), 2(Integer), 2021-08-25 05:03:39.0(Timestamp), 2021-08-25 05:02:41.0(Timestamp), 2(Integer), 3(Long), 1(Integer)

注意:在更新前我们一定要先查询到version设置到实体类上再进行更新才能生效

3.2 多插件配置问题

​ 我们在使用3.4.0版本以后的MP时,如果需要用到多个插件的话要注意。在配置的时候只需要注入一个MybatisPlusInterceptor对象,把插件对象添加到MybatisPlusInterceptor对象中即可。

例如:

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
    mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
    mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    return mybatisPlusInterceptor;
}

注意:

使用多个功能需要注意顺序关系,建议使用如下顺序

  • 多租户,动态表名
  • 分页,乐观锁
  • sql 性能规范,防止全表更新与删除

总结: 对 sql 进行单次改造的优先放入,不对 sql 进行改造的最后放入

详情查看:https://baomidou.com/pages/2976a3/

2

评论区