myBatisPlus-修改操作

根据主键进行修改

@Test
public void updateById() {
    User user = new User();
    user.setId(3L);
    user.setAge(30);
    int result = userMapper.updateById(user);
    System.out.println(result);
}

在数据库当中,添加两个字段,每次添加数据或者修改数据的时候不用都要自己来去设置,通过 mp 自己来去设置,添加的两个字段分别为创建时间,和更新时间

ALTER TABLE `mybatisplus_db`.`user` 
ADD COLUMN `create_time` datetime NULL COMMENT '创建时间' AFTER `email`,
ADD COLUMN `update_time` datetime NULL COMMENT '更新时间' AFTER `create_time`;

自动填充

修改实体类,在刚刚添加的两个属性上分别添加注解,mp 采用的是驼峰命名,所以实体类需要遵守 mp 的驼峰

/**
 * @author BNTang
 */
@Data
@TableName("user")
public class User {

    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}

然后创建一个 handle 在实现元对象处理器接口

/**
 * @author BNTang
 **/
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }

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

然后你在运行之前写的插入,更新你会发现刚刚添加的那几个时间字段会帮我们更新,Handle 必须交给 Spring 进行管理才会生效

悲观锁与乐观锁

更新丢失问题,并发状态下,多个人同时修改同一条记录,最后提交的会把之前的提交数据覆盖

悲观锁

一个人操作时, 不允许另一个人再次操作

乐观锁

使用一个额外的字段 version,取出记录时,获取当前 version,更新时,带上这个 version, 把 version 值 +1

乐观锁实现

先在数据库中添加 version 字段,SQL 如下

ALTER TABLE `mybatisplus_db`.`user`
ADD COLUMN `version` int NULL AFTER `update_time`;

实体类中添加 version 字段

/**
 * @author BNTang
 */
@Data
@TableName("user")
public class User {

    // @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

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

    @Version
    @TableField(fill = FieldFill.INSERT)
    private Integer version;
}

/**
 * @author BNTang
 **/
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
        this.setFieldValByName("version", 1, metaObject);
    }

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

配置乐观锁插件

新建 config 包,新建一个配置类如下所示

/**
 * @author BNTang
 **/
@Configuration
public class Config {

    /**
     * 乐观锁插件
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}

测试一下如上做的配置看看是否实现了乐观锁呢,在测试类当中添加如下代码然后执行发现运行结果已经实现了乐观锁机制了如下图

@Test
public void selectUpdateById() {
    // 先查询
    User user = userMapper.selectById(1373115128545820674L);

    // 修改数据
    user.setName("Jonathan_Lee");

    // 执行更新
    userMapper.updateById(user);
}

模拟取出数据后,数据库中的 version 实际数据比取出的值大,即已被其它线程修改并更新了 version

把版本号变小,发现代码能执行成功,但是没有修改成功,修改一下如上的代码来模拟一下如下

@Test
public void selectUpdateByIdOptimisticLocking() {
    // 先查询
    User user = userMapper.selectById(1373115128545820674L);

    // 修改数据
    user.setName("Jonathan_Lee_Test");
    user.setVersion(user.getVersion() - 1);

    // 执行更新
    userMapper.updateById(user);
}

posted @ 2021-03-20 11:57  BNTang  阅读(634)  评论(0编辑  收藏  举报