1.修改操作

注意: update时生成的sql自动是动态sql: UPDATE user SET name = ? WHERE id=?

  1. //修改操作
  2. @Test
  3. public void Update() {
  4. User user = new User();
  5. user.setId(1508424863220776962L);
  6. user.setName("张三丰");
  7. // 返回影响行数,修改1个数据,就影响一行
  8. int count = userMapper.updateById(user);
  9. System.out.println("影响行数" + count);
  10. }

自动填充和乐观锁 - 图1

2.自动填充

需求描述:在项目中经常会遇到一些数据,每次都使用相同的方式进行填充,例如记录的创建时间和更新时间等。

而我们可以使用Mybatis Plus的自动填充功能,来完成这些的字段的赋值工作。

为了演示Mybatis-Plus的自动填充的过程,我们需要修改User表:添加2个新的datatime类型字段create_time、update_time。

自动填充和乐观锁 - 图2

与之对应的,我们也要修改相应的实体类。

@Data
public class User {
    //
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;

    private String name;
    private Integer age;
    private String email;
    //  驼峰命名  对应的数据库的字段create_time、update_time
    private Date createTime;
    private String updateTime;

}

1.添加注解

为实体类中要自动填充的属性添加注解

    //  驼峰命名  对应的数据库的字段create_time、update_time
    @TableField(fill= FieldFill.INSERT)
    private Date createTime;
    @TableField(fill=FieldFill.INSERT_UPDATE)
    private String updateTime;

2.创建实现类:实现元对象处理器的接口

创建实现类,实现接口中的2个方法, 一个方法添加执行,另一个方法更新执行。

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    // 当Mybatis-plus执行添加操作时,此方法就会执行
    @Override
    public void insertFill(MetaObject metaObject) {
        /**  通过相应的字段名赋值该字段值
         *  此方法有3个参数
         *  fieldName : 字段名
         *  fieldVal : 字段值
         *  metaObject: 元对象
         *
         *  在本业务中,我们添加一个对象,就自动填充创建时间;
         *  这里的时间就是当前时间 new Date();
         */
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
    // 当Mybatis-plus执行修改操作时,此方法就会执行
    @Override
    public void updateFill(MetaObject metaObject) {
        /**  通过相应的字段名赋值该字段值
         *  此方法有3个参数
         *  fieldName : 字段名
         *  fieldVal : 字段值
         *  metaObject: 元对象
         *
         *  在本业务中,我们修改一个对象,就自动填充更新时间;
         *  这里的时间就是当前时间 new Date();
         */
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

注意:不要忘记添加@Componet ,将元对象处理器交给Spring进行管理。

@Component (把普通pojo实例化到spring容器中,相当于配置文件中的 )

泛指各种组件,就是说当我们的类不属于各种归类的时候(不属于@Controller、@Services等的时候),我们就可以使用@Component来标注这个类。

如果您还不太了解@Component 注解,请先仔细学习@Componet注解的作用原理与功能

运行测试类的添加和修改操作,看看效果:

自动填充和乐观锁 - 图3

自动填充和乐观锁 - 图4

乐观锁

什么是乐观锁?

乐观锁( Optimistic Locking):顾名思义,对加锁持有一种乐观的态度,即先进行业务操作,不到最后一步不进行加锁,”乐观”的认为加锁一定会成功的,在最后一步更新数据的时候再进行加锁。

为什么要使用乐观锁呢?假设,现在同时有多人(至少2个人),主管A和主管B要修改小张的工资。小张的工资为5000元,而主管A认为小张最近表现很好,要增加他的工资,修改他的工资5000元到7000元;另一位主管B认为小张表现令他特别满意,表现十分优秀。并且提议要增加小张的工资由5000元增加到9000元。遇到这种情况怎么办?如果没有乐观锁,那么会出现如下情况:主管A修改5000到7000,而执行主管B的操作时,小张工资不再是5000元,二是7000元。那么5000元到9000元的操作就会执行错误。

那么怎么实现乐观锁呢?很简单,再添加一个字段version

version方式:一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。

sql实现代码:

update table 
set x=x+1, version=version+1 
where id=#{id} and version=#{version};

如果您还有兴趣,可以了解一下悲观锁

现在就开始实现乐观锁。

(1).修改实体类

在实体类User中添加新的属性version,并添加注解@Version,并且在与之对应的数据库添加intversion字段

@Data
public class User {
    //
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;

    private String name;
    private Integer age;
    private String email;
    //  驼峰命名  对应的数据库的字段create_time、update_time
    @TableField(fill= FieldFill.INSERT)
    private Date createTime;
    @TableField(fill=FieldFill.INSERT_UPDATE)
    private Date updateTime;
    @Version
    private  Integer   version;

}

(2).创建配置文件

创建包config,创建文件MpConfig.java,而此时可以删除主类中的@MapperScan扫描注解。

(3).注册乐观锁插件

在MpConfig中注册@Bean

@Configuration
@MapperScan(" com.example.demomp.mapper")
public class MpConfig  {
    /**
     * 乐观锁插件
     *  注意在Mybatis-plus3.4.0版本后,放弃此方法乐观锁处理器
     * */

    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }

}

注意:别忘记添加==@Configuration注解以及@MapperScan扫描注解==

4.测试乐观锁

    // 测试乐观锁

    @Test
    public void OptimisticInsert() {
        // 查询ID,获得对象
        User user = userMapper.selectById(1508686375965462530L);
        // 这里无需设置version,Mybatis-plus会自动帮我们填充修改
        user.setAge(25);
        //  返回影响行数,修改1个数据,就影响一行
        int count = userMapper.updateById(user);
    }

我们可以看一看测试结果

自动填充和乐观锁 - 图5