MybaitsPlus修改操作:乐观锁与自动填充

本文介绍了MyBatisPlus(MP)中的自动填充功能,用于在插入和更新时自动设置如创建时间和更新时间等字段。此外,还详细讲解了乐观锁的概念和实现方式,包括在数据库中添加version字段,实体类中添加version注解,以及如何在元对象处理器中处理version值。乐观锁通过版本号避免了丢失更新问题,确保了数据的并发安全性。
摘要由CSDN通过智能技术生成

修改操作

根据ID更新操作

这里MP作了优化,需要改什么值你就set什么值,不改的值不需要管

//修改操作
@Test
public void testUpdate(){
    User user = new User();
    user.setId(2L);  //只需要修改ID属性,会自动找
    user.setAge(20); //直接修改对象传入即可更新
    userMapper.updateById(user); //直接传入一个对象
}

⚠️update时底层生成的sql自动是动态sql:UPDATE user SET age=? WHERE id=?

⭐️MP的自动填充功能

项目中经常会遇到一些数据每次都使用相同的方式填充,例如一条记录的创建时间,更新时间等。除了每次自己手动set外,还可以使用MyBatis Plus的自动填充功能完成这些字段的赋值工作。

第一步:在实体上添加注解

@Data
public class User {
     ......
    @TableField(fill = FieldFill.INSERT) //插入时
    private Date createTime;
    //@TableField(fill = FieldFill.UPDATE)
    @TableField(fill = FieldFill.INSERT_UPDATE) //插入和更新时
    private Date updateTime; 
}

第二步:创建配置类实现MetaObjectHandler接口及其中的方法。

@Component //别忘
public class MyMetaObjectHandler implements MetaObjectHandler {
    //使用MP执行添加操作时执行这个方法
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }


    //使用MP执行更新操作时执行这个方法
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }
}

之后再执行相关操作就会自动将这两个字段填充好。

什么是元数据(meta data)?

描述数据的数据,例如用户数据表中,用户的ID、年龄、姓名就是元数据。

😣乐观锁

乐观锁主要解决丢失更新问题,当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新。

MySQL读写问题回顾
读问题

不考虑事务隔离性,可能会产生读问题。分为脏读、不可重复读、幻读

事务就好比操作系统中的原语,是一个最小的原子操作,隔离性是指一个事务的执行不能被其他事务干扰

  • 脏读:指当一个事务对数据进行了修改,且修改还没有提交到数据库中,这时另外一个事务也访问这个数据,然后使用了这个数据,读错了错误的数据
  • 不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的,称为不可重复读。
  • 幻读:是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
写问题

写问题主要是指丢失更新问题,只有在并发的情况下才可能出现这种问题。多个人同时修改同一条记录,最后提交的数据覆盖了另一个提交的数据。(同时写)

有悲观锁和乐观锁两种解决方法。

悲观锁(不推荐)

悲观锁即一个用户修改记录时,其余所有人都不准修改直到该用户修改完毕。

乐观锁

乐观锁通过引入版本号这个概念来解决丢失更新问题

image-20210315205533160
乐观锁实现方式
  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败
Mybatis中的乐观锁

MP提供了非常方便的乐观锁实现方法,具体实现步骤:

  1. 在数据库中添加version字段

    ALTER TABLE `user` ADD COLUMN `version` INT
    
  2. 实体类添加version字段并注解

    //乐观锁版本号
    @Version
    @TableField(fill = FieldFill.INSERT)
    private Integer version; //整数类型下version自动+1
    
  3. 元对象处理器接口添加versioninsert默认值

    @Override
    public void insertFill(MetaObject metaObject) {
        ...
        //version的默认值设置为1
        this.setFieldValByName("version", 1, metaObject); 
    }
    
  4. 在配置类中将乐观锁插件注册为Bean

    @EnableTransactionManagement
    @Configuration
    @MapperScan("com.atguigu.mybatis_plus.mapper") //启动类中不用再写
    public class MybatisPlusConfig {
        //乐观锁插件
        @Bean
        public OptimisticLockerInterceptor optimisticLockerInterceptor() {
            return new OptimisticLockerInterceptor();
        }
    }
    
  5. 测试

    //测试乐观锁:先查再改
    @Test
    public void testOptimisticLocker(){
        User user = userMapper.selectById(1373929950268137474L);
        user.setAge(200);
        //修改后乐观锁版本号变成+1
        userMapper.updateById(user);
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值