开发者

MybatisPlus字段自动填充&乐观锁的方法实现

目录
  • 1.使用步骤
    • 1.定义实体类
    • 2.编写填充处理器
    • 3.ID生成策略
    • 4.测试代码
      • 1.testInsert():测试插入操作
      • 2.testUpdate():基于条件更新
      • 3.testUpdate1():基于实体主键更新
  • 2.注意事项

    MyBATis-Plus 提供了一个便捷的自动填充功能,用于在插入或更新数据时自动填充某些字段,如创建时间、更新时间等。

    自动填充功能通过实现 comphp.baomidou.mybatisplus.core.handlers.MetaObjectHandler 接口来实现。

    1.使用步骤

    1.定义实体类

    @TableField(fill = FieldFill.INSERT):表示该字段在执行 insert 操作时进行填充。

    @TableField(fill = FieldFill.INSERT_UPDATE):表示该字段在执行 insert 和 update 操作时进行填充。

    LocalDateTime:这里使用 LocalDateTime 作为时间类型,也可以使用 Date 或 Instant 等

    @Data
    public class User {
        private Long id;
        private String name;
        @TableField(value = "pwd",select = false)
        private String pphpassword;
        private Integer age;
        private String tel;
        @TableField(exist = false)
        private String online;
        private Integer deleted;
    
        /http://www.devze.com/ 只在插入时自动填充字段
        @TableField(fill = FieldFill.INSERT)
        private LocalDateTime  createTime;
    
        // 在插入和更新时填充字
        @TableField(fill = FieldFill.INSERT_UPDATE)
        private LocalDateTime updateTime;
    
        private String updateUser;
    }

    2.编写填充处理器

    创建一个类来实现 MetaObjectHandler 接口,并重写 insertFill 和 updateFill 方法。

    @Slf4j
    @Component
    public class MyMetaObjectHandler implements MetaObjectHandler {
        @Override
        public void insertFill(MetaObject metaObject) {
            log.info("开始插入填充...");
            // 创建时间字段只需要在创建这条记录的时候填充当前时间
            this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
            // 更新数据的人,在插入一条记录的时候要把这个人记录到数据库
            this.strictInsertFill(metaObject, "updateUser", String.class, "admin");
            // 更新时间,在插入一条记录的时候要把当前时间记录到数据库
            this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
        }
        @Override
        public void updateFill(MetaObject metaObject) {
            log.info("开始更新填充...");
            // 更新某条记录的时候,把该记录的更新的人记录
            // this.strictUpdateFill(metaObject, "updateUser",String.class, "zhangsan");
            // 更新时间字段,在更新一条记录的时候要把当前时间记录到数据库
            // this.strictUpdateFill(metaObject, "updateTime",LocalDateTime.class, LocalDateTime.now());
            // this.strictUpdateFill(metaObject, "updateTime",LocalDateTime.class, LocalDateTime.now());
            this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
            this.setFieldValByName("updateUser", "zhangsan", metaObject);
        }
    }

    3.ID生成策略

    • id生编程成策略问题在实际工作中具备很强的现实意义。我们现在实验过程中数据库的id直接用 数字1、2、3来写,是非常危险的,很容易被人“拖库”,因此需要保证数据库中的数据记录 具备“无序性”。MP给我们提供了多种ID生成策略,可以在配置文件中配置这种策略。
    • “拖库” 指的是攻击者通过漏洞或非法手段获取整个数据库的完整备份(即“拖走数据库”)。如果数据库中的主键 ID 是连续的数字(如 1、2、3),攻击者可以轻松遍历所有记录,批量爬取敏感数据,甚至进一步发起注入攻击。因此,使用无序、非连续的 ID 生成策略是提升数据库安全性的重要手段。
    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
      global-config:
        db-config:
        # 主键自增
          id-type: auto
          # 表前缀
          table-prefix: tbl_
          logic-delete-field: deleted
          logic-delete-value: 1
          logic-not-delete-value: 0

    4.测试代码

    1.testInsert():测试插入操作

    • 功能:向数据库插入一条新的用户记录。

    • 关键点

      • 使用 userMapper.insert(user) 方法,直接传入实体对象。

      • MyBatis-Plus 会自动生成主键(如配置了 @TableId 或全局主键策略)。

    2.testUpdate():基于条件更新

    • 功能:根据条件更新指定字段。

    • 分析

      • 使用 UpdateWrapper 动态构建更新条件。

      • userUpdateWrapper.set("name", "更887"):直接指定更新的字段名和值。

      • userUpdateWrapper.eq("id", "1916126238607409154"):通过 eq 方法设置 WHERE 条件。

      • 调用 userMapper.update(userUpdateWrapper) 执行更新。

    3.testUpdate1():基于实体主键更新

    功能:先查询后更新,通过实体主键更新记录。

    分析

    • 通过 userMapper.selectById("1916131310603149314") 查询用户。
    • 修改实体属性后,调用 userMapper.updateById(user) 更新。
    • MyBatis-Plus 会根据实体中的 @TableId 自动生成 WHERE 条件(如 WHERE id = ?)。
    • 支持自动填充(如 updateTime 字段)。
     @Test
        public void testInsert() {
            User user = new User();
            user.setName("张99");
            user.setAge(19);
            user.setTel("123456789");
            user.setPassword("123456");
            int insert = userMapper.insert(user);
            System.out.println("insert:"+insert);
        }
        @Test
        public void testUpdate() {
            UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
            userUpdateWrapper.set("name", "更887");
            userUpdateWrapper.eq("id", "1916126238607409154");
            userMapper.update(userUpdateWrapper);
        }
        @Test
        public void testUpdate1() {
            User user = userMapper.selectById("1916131310603149314");
            // 假设ID为1的用户存在
            user.setName("updatedUser");
            int result = userMapper.updateById(user);
            System.out.println("影响行数:" + result);
            System.out.println("更新后的用户更新时间:" + user.getUpdateTime());
        }

    2.注意事项

    • 自动填充是直接给实体类的属性设置值。
    • 如果属性没有值,入库时会是 null
    • MetaObjectHandler 提供的默认方法策略是:如果属性有值则不覆盖,如果填充值为 null 则不填充。
    • 字段必须声明 @TableField 注解,并设置 fill 属性来选择填充策略。
    • 填充处理器需要在 Spring Boot 中声明为 @Component 或 @Bean
    • 使用 strictInsertFill 或 strictUpdateFill 方法可以根据注解 FieldFill.xxx、字段名和字段类型来区分填充逻辑。
    • 如果不需区分,可以使用 fillStrategy 方法。
    • 在 update(T entity, Wrapper<T> updateWrapper) 时,entity 不能为空,否则自动填充失效。
    • 在 update(Wrapper<T> updateWrapper) 时不会自动填充,需要手动赋值字段条件。

    到此这篇关于MybatisPlus字段自动填充&乐观锁的方法实现的文章就介绍到这了,更多相关MybatisPlus字段自动填充&乐观锁内容请搜索编程客栈(wwwQyQTPZC.cppcns.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜