Mybatis-Plus 自动填充失效问题解决

 更新时间:2024年10月23日 11:06:09   作者:Excellent的崽子  
在使用MyBatis-Plus时,自动填充功能可能会失效,这通常与版本和配置有关,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

确认版本

首先确认你的项目中使用的 mybatis-plus 版本是 3.3.0 以下还是 3.3.0 以上(包含 3.3.0),在低版本和高版本中重写 MetaObjectHandler 方法的 insertFill 和 updateFill 的写法是不同的,比如下面示例:

@Bean
public MetaObjectHandler metaObjectHandler(){

    return new MetaObjectHandler() {
        @Override
        public void insertFill(MetaObject metaObject) {
            this.setFieldValByName("createdDate", new Date(), metaObject);
            this.setFieldValByName("updatedDate", new Date(), metaObject);
        }
            @Override
        public void updateFill(MetaObject metaObject) {
            this.setFieldValByName("updatedDate", new Date(), metaObject);
        }
    };
}

这是使用 MyBatis-Plus 早期版本(在 3.3.0 之前)的自定义 MetaObjectHandler 实现。它使用 setFieldValByName 方法来设置 createdDate 和 updatedDate 字段的值。这种方法使用的是 java.util.Date 类型。

    @Bean
    public MetaObjectHandler metaObjectHandler(){
        return new MetaObjectHandler() {
            @Override
            public void insertFill(MetaObject metaObject) {
                this.strictInsertFill(metaObject, "createdDate", Date.class, new Date());
                this.strictInsertFill(metaObject, "updatedDate", Date.class, new Date());
            }

            @Override
            public void updateFill(MetaObject metaObject) {
                this.strictUpdateFill(metaObject, "updatedDate",  LocalDateTime.class, LocalDateTime.now());
            }
        };
    }

这是使用 MyBatis-Plus 3.3.0 及以上版本中引入的更高级的填充策略。它使用 strictInsertFill 和 strictUpdateFill 方法,这些方法更加类型安全,也提供了更灵活的填充选项。此版本推荐使用 java.time.LocalDateTime 类型,这符合 Java 8 及更高版本中引入的时间 API,提供了更好的日期和时间处理能力。
详细对比:

类型安全性

第二种写法中,strictInsertFill 和 strictUpdateFill 方法允许你指定目标字段的数据类型(例如 LocalDateTime.class),从而避免了类型转换错误。

第一种写法中,setFieldValByName 方法需要你自己确保字段类型和赋值类型的一致性。

默认值提供方式

第二种写法中,你可以直接传递一个 LocalDateTime.now() 表达式,或者使用 lambda 表达式 () -> LocalDateTime.now() 来提供一个延迟执行的默认值。这在某些情况下可能更有用,比如当你的默认值依赖于一些业务逻辑时。

第一种写法直接使用 new Date() 创建日期实例,没有提供延迟执行的机制。

兼容性和 bug 修复

第二种写法是 MyBatis-Plus 推荐的最新实践,通常意味着它有更好的兼容性和已知问题的修复。

第一种写法可能在新版本中不再得到支持,或存在未解决的 bug,例如 fillStrategy 方法在 3.3.0 版本中有 bug。

检查配置

首先是引入高版本的 pom 依赖:

<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-boot-starter</artifactId>
  <version>3.3.0</version>
</dependency>

编写mybatis-plus的配置类

/**
 * MyBatis-Plus配置类
 */
@MapperScan("com.demo.mapper") // 定义项目中的 mapper 路径
@Configuration
public class MybatisPlusConfig {

    /**
     * mybatis-plus 自动填充配置
     */
    @Bean
    public MetaObjectHandler metaObjectHandler(){
        return new MetaObjectHandler() {
            @Override
            public void insertFill(MetaObject metaObject) {
                /**
                  * 第一个参数 metaObject 这里面包含了你传入的实体类
                  * 第二个参数要和实体类中的属性名保持一致
                  * 第三个参数要跟实体类中的属性类型保持一致
                  * 第四个参数是你设置的填充默认值
                  */      
                this.strictInsertFill(metaObject, "createdDate", Date.class, new Date());
                this.strictInsertFill(metaObject, "updatedDate", Date.class, new Date());
            }

            @Override
            public void updateFill(MetaObject metaObject) {
                this.strictUpdateFill(metaObject, "updatedDate",  Date.class, new Date());
            }
        };
    }

}

在实体类中,你需要使用 @TableField 注解来标记哪些字段需要自动填充,并指定填充的策略。

public class User {
    @TableField(fill = FieldFill.INSERT)
    private String createTime;

    @TableField(fill = FieldFill.UPDATE)
    private String updateTime;

    // 其他字段...
}

delete 和 update 方法的区别

在 MyBatis-Plus 中,`delete` 方法和 `update` 方法的行为差异主要源于它们对 `MetaObjectHandler` 中定义的自动填充逻辑的调用时机和方式的不同。

对于 update方法:

当你使用 update 方法时,MyBatis-Plus 会调用 MetaObjectHandler 的 updateFill 方法。这是因为 update 方法本质上是一个更新操作,它会触发自动填充逻辑,尤其是那些被标记为 FieldFill.UPDATE 或 FieldFill.INSERT_UPDATE 的字段。

对于 delete 方法:

当使用 delete 方法时,情况就有所不同了。默认情况下,delete 方法不会触发 MetaObjectHandler 的 updateFill 方法,即使你正在使用逻辑删除(即,delete 方法实际上执行的是一个 UPDATE 语句来修改一个逻辑删除标志)。这是因为在 MyBatis-Plus 的设计中,delete 方法的目的就是删除记录,无论是物理删除还是逻辑删除,它都不会触发更新字段的自动填充逻辑。

然而,当你在实体类中使用了 @TableLogic 注解并配置了逻辑删除,MyBatis-Plus 的 delete 方法会执行一个 UPDATE 语句来改变逻辑删除字段的值,但它不会执行 updateFill 方法来更新其他字段,如 updatedDate。这是 MyBatis-Plus 的设计决策,它将 delete 和 update 视为不同的操作,即使在逻辑删除的情况下,delete 方法也不会触发常规的更新字段填充。

注意事项

  • 如果你手动的设置了自动填充的值,那么 MyBatis-Plus 的自动填充策略不会覆盖这个值。
  • 字段必须声明 @TableField 注解,并设置 fill 属性来选择填充策略。
  • 填充处理器需要在 Spring Boot 中声明为 @Component 或 @Bean
  • 在 update(T entity, Wrapper<T> updateWrapper) 时,entity 不能为空,否则自动填充失效。
  • 在 update(Wrapper<T> updateWrapper) 时不会自动填充,需要手动赋值字段条件。

到此这篇关于Mybatis-Plus 自动填充失效问题解决的文章就介绍到这了,更多相关Mybatis-Plus 自动填充失效内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • SpringBoot中静态访问配置属性的解决方案对比

    SpringBoot中静态访问配置属性的解决方案对比

    在SpringBoot开发中,静态访问配置信息是一个常见需求,尤其是在工具类中直接获取配置值,下面我们就来看看几个常用的方法,大家可以根据需要选择
    2025-03-03
  • Java Socket实现多人聊天系统

    Java Socket实现多人聊天系统

    这篇文章主要为大家详细介绍了Java Socket实现多人聊天系统,具有图形界面,实现文件传输功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • Java二进制操作(动力节点Java学院整理)

    Java二进制操作(动力节点Java学院整理)

    这篇文章给大家介绍了java二进制操作技巧,包括移位、位运算操作符等相关知识点,非常不错,感兴趣的朋友参考下吧
    2017-03-03
  • SpringBoot实现配置文件自动加载和刷新的示例详解

    SpringBoot实现配置文件自动加载和刷新的示例详解

    在使用Spring Boot开发应用程序时,配置文件是非常重要的组成部分,在不同的环境中,我们可能需要使用不同的配置文件,当我们更改配置文件时,我们希望应用程序能够自动加载和刷新配置文件,本文我们将探讨Spring Boot如何实现配置文件的自动加载和刷新
    2023-08-08
  • 反射机制:getDeclaredField和getField的区别说明

    反射机制:getDeclaredField和getField的区别说明

    这篇文章主要介绍了反射机制:getDeclaredField和getField的区别说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Java面向对象之抽象类,接口的那些事

    Java面向对象之抽象类,接口的那些事

    这篇文章主要介绍了Java面向对象基础:抽象类和接口,文中代码可以帮助各位更好的理解学习,有需求的小伙伴可以参考下,希望能够给你带来帮助
    2021-08-08
  • SpringBoot实现动态插拔的AOP的完整案例

    SpringBoot实现动态插拔的AOP的完整案例

    在现代软件开发中,面向切面编程(AOP) 是一种非常重要的技术,能够有效实现日志记录、安全控制、性能监控等横切关注点的分离,在传统的 AOP 实现中,切面逻辑往往是固定的,难以动态调整,本文将详细探讨如何利用 Spring Boot 实现动态插拔的 AOP,需要的朋友可以参考下
    2025-01-01
  • 关于实体类中Date属性格式化@JsonFormat @DateTimeFormat

    关于实体类中Date属性格式化@JsonFormat @DateTimeFormat

    这篇文章主要介绍了关于实体类中Date属性格式化@JsonFormat @DateTimeFormat问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • SpringBoot3整合邮件服务实现邮件发送功能

    SpringBoot3整合邮件服务实现邮件发送功能

    本文介绍了spring boot整合email服务,实现发送验证码,邮件(普通文本邮件、静态资源邮件、附件邮件),文中通过代码示例介绍的非常详细,坚持看完相信对你有帮助,需要的朋友可以参考下
    2024-05-05
  • springboot+mybatis-plus实现内置的CRUD使用详解

    springboot+mybatis-plus实现内置的CRUD使用详解

    这篇文章主要介绍了springboot+mybatis-plus实现内置的CRUD使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12

最新评论