MyBatis-Plus学习笔记(三) 更新操作-自动填充-乐观锁

狂神说Java:https://www.bilibili.com/video/BV17E411N7KN?p=8学习笔记


一、更新数据

@Test
    public void updateTest(){

        User user = new User();
        user.setId(1L);
        user.setName("README");
        user.setAge(18);
        user.setEmail("[email protected]");

        //由源码知:虽然方法名叫updateById,但参数是对象

        int result = userMapper.updateById(user); 

        System.out.println(result);
    }

二、自动填充

创建时间,修改时间这些操作一般都是自动完成的(不希望手动更新)。自动更新有两种方式

方式一:在数据库中配置(工作中不建议使用)

方式二:

  • 在实体类中字段属性上添加注解
//字段添加填充内容
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
  • 编写处理器处理此注解
@Slf4j
@Component              //要把处理器加到IOC容器中
public class MyMetaObjectHandler implements MetaObjectHandler {

    //插入时的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }

    //更新时的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

三、乐观锁

  • 乐观锁:总是认为不会出现问题,无论干什么都不去上锁。如果出现了问题,再次更新值测试
  • 悲观锁:总是认为会出现问题,无论干什么都会上锁,再去操作

实现方式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败
--A
update user set name = "README",version = version + 1
where id = 2 and version = 1

--B 线程抢先完成,这时候version = 2,会导致A修改失败!
update user set name = "README",version = version + 1
where id = 2 and version = 1

1.给数据库中加version字段

2.在实体类中添加对应字段及乐观锁注解@version

  //乐观锁version注解
    @Version          
    private Integer version;

3.注册组件

@MapperScan("com.zhou.mapper")
@EnableTransactionManagement
@Configuration //代表这是配置类
public class MyBatisPlusConfig {

    //注册乐观锁
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
        return new OptimisticLockerInterceptor();
    }
}

4.测试

    //单线程测试成功
    @Test
    public void testOptimisticLocker(){
        //查询用户信息
        User user = userMapper.selectById(1L);
        //修改用户信息
        user.setName("Morning");
        user.setEmail("[email protected]");
        //执行更新操作
        userMapper.updateById(user);
    }

   //多线程测试失败
    @Test
    public void testOptimisticLocker(){

        User user = userMapper.selectById(1L);
        user.setName("Morning");
        user.setEmail("[email protected]");

        //user2插队操作
        User user2 = userMapper.selectById(1L);
        user2.setName("night");
        user2.setEmail("[email protected]");
        userMapper.updateById(user2);

        //如果没有乐观锁,它会覆盖插队线程的值
        //可以用自旋锁来尝试多次提交
        userMapper.updateById(user);
    }

猜你喜欢

转载自blog.csdn.net/qq_41694490/article/details/114269882