zoukankan      html  css  js  c++  java
  • MP(MyBatis-Plus)实现乐观锁更新功能

    实现步骤

    step1:添加乐观锁拦截器

    MP的其他拦截器功能可以参考官网

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

    step2:配置Entity

    @TableField(fill = FieldFill.UPDATE)
    @Version
    private Date updateTime;
    

    用更新字段充当版本号。

    • 上面的配置需要注意的是:updateTime既配置自动填充,又配置了乐观锁功能。MP在进行处理时会先进行乐观锁处理,然后再进行自动填充。
    • 问题:前端送了id和一些需要更新的字段过来,每次需要从数据库中查出version,然后再进行更新(要么前端将版本号传过来);
    • 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime;
    • 仅支持 updateById(id) 与 update(entity, wrapper) 方法,在 update(entity, wrapper) 方法下, wrapper 不能复用!!!
    • 对于updateTime这个字段,在数据库中建议设置成时区不相关的时间戳类型。

    多说一点

    使用updateTime作为版本号可能会存在一些问题。

    我们通常需要将updateTime返回给前端页面,假如我们不做任何设置,返回前端的数据大概是下面的样子:

    {
      "userId": 367,
      "address": "上海市自由之路xxxxxx...",
      "workUnit": "XXXX",
      "createTime": "2020-12-22T00:00:00.000+08:00",
      "updateTime": "2021-01-08T17:28:14.782+08:00"
    }
    

    这种时间格式可能不是前端页面需要的,这是我们可以进行如下设置;

    spring:
      jackson:
        default-property-inclusion: non_null
        time-zone: GMT+8
        date-format: yyyy-MM-dd HH:mm:ss
    

    返回的数据

    {
     "userId": 367,
     "address": "上海市自由之路xxxxxx...",
     "workUnit": "XXXX",
     "createTime":"2020-12-22 00:00:00",
     "updateTime":"2021-01-08 17:28:14"
    }
    

    经过这个配置后,就可以得到可读性比较好的时间格式了。但是我们需要注意的时候,这个时间的精度其实已经丢失了,当前提交修改数据到后端,这个值和数据库中的值已经不相等了。所以永远不能将数据更新成功。

    所以这种情况下使用updateTime来进行乐观锁更新就不太适合了。可以考虑在表中另外加一个字段version来进行乐观锁更新。

    但其实还是有比较好的解决办法的。

    首先,我们不要对返回的时间格式进行全局话配置。

    spring:
      jackson:
        default-property-inclusion: non_null
        time-zone: GMT+8
        # date-format: yyyy-MM-dd HH:mm:ss
    

    然后,添加一个updateTime的备份字段updateTimeSimpleFormat,并对这个字段进行单独的时间格式化。

    private Date updateTime;
    
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTimeSimpleFormat;
    

    updateTimeSimpleFormat不要生成get和set方法,在updateTime的set方法中对updateTimeSimpleFormat进行赋值。

    public void setUpdateTime(Date updateTime) {
          this.updateTime = updateTime;
          this.updateTimeSimpleFormat = updateTime;
      }
    

    这样就既能满足前端返回格式化的时间,后端又能获取到乐观锁的版本号。

    但是,这个方法比较不好的地方,就是必须对每个时间格式进行@JsonFormat注解配置,不能进行全局配置,比较繁琐。

    总结:使用updateTime作为乐观锁的优点就是不需要再新加字段,比较简洁。但是带来的问题上面已经讲的很清楚了。还是印证了那个真理:没有完美的技术,只有适合的技术。

  • 相关阅读:
    javaScript第一篇
    数据结构与算法学习笔记2018-01-30
    各种编程技术文章收集链接
    git最简单直接粗爆与github教程
    Word2Vec原理之Negative Sample
    Word2Vec原理之层次Softmax算法
    统计语言模型
    各种优化方法总结比较(sgd/momentum/Nesterov/adagrad/adadelta)
    TensorBoard:可视化学习
    Batch Normalization
  • 原文地址:https://www.cnblogs.com/54chensongxia/p/14253188.html
Copyright © 2011-2022 走看看