首页 区块链

Maven多模块项目:MyBatis Plus 自动填充日期失效排查与解决

分类:区块链
字数: (8321)
阅读: (6945)
内容摘要:Maven多模块项目:MyBatis Plus 自动填充日期失效排查与解决,

最近在做一个基于 Spring Boot + MyBatis Plus 的 Maven 多模块项目时,遇到了一个很奇怪的问题:MyMetaObjectHandler 配置的自动填充日期功能失效了。简单来说,就是数据库表中的 create_timeupdate_time 字段本应该由 MyMetaObjectHandler 在插入和更新时自动填充,但实际写入数据库的却是 null。经过一番排查,最终解决了这个问题,这里记录一下。

问题场景重现

项目结构如下:

parent-module
├── common-module  # 公共依赖和配置
├── dao-module     # MyBatis Plus 相关配置和实体类
├── service-module # 业务逻辑
└── web-module     # Controller

MyMetaObjectHandler 定义在 common-module 中,目的是为了在各个模块中共享。实体类定义在 dao-module 中,并且使用了 MyBatis Plus 的注解。在 web-module 中调用 service-module 的接口进行数据操作,期望 MyMetaObjectHandler 能够自动填充日期,但实际并没有生效。

Maven多模块项目:MyBatis Plus 自动填充日期失效排查与解决

底层原理深度剖析

MyBatis Plus 的 MetaObjectHandler 机制是通过拦截 MyBatis 的 Executor 接口来实现的。当执行 insertupdate 操作时,MyBatis Plus 会检查是否存在实现了 MetaObjectHandler 接口的类,如果存在,则会调用其 insertFillupdateFill 方法。这两个方法可以对实体类的属性进行赋值,从而实现自动填充的功能。

失效的原因往往在于以下几个方面:

Maven多模块项目:MyBatis Plus 自动填充日期失效排查与解决
  1. 扫描路径配置错误:Spring Boot 默认只会扫描启动类所在包及其子包下的 Bean。如果 MyMetaObjectHandler 没有被扫描到,Spring 容器就无法管理它,自然就无法生效。
  2. 配置类冲突:如果多个模块都配置了 MyBatis Plus 的相关配置,可能会导致配置冲突,从而影响 MetaObjectHandler 的生效。特别是 @MapperScan 注解容易出现冲突。
  3. 事务管理问题:如果 insertupdate 操作没有被事务管理,可能会导致 MetaObjectHandler 在某些情况下无法正常工作。尤其是在涉及到多个数据源、分布式事务的情况下,更容易出现问题。
  4. 模块依赖问题:如果各个模块之间的依赖关系没有正确配置,可能会导致 MyMetaObjectHandler 无法被正确加载。

代码和配置解决方案

针对上述可能的原因,需要逐一排查并解决。以下是一个可行的解决方案:

  1. 确保 MyMetaObjectHandler 被 Spring 扫描到

在启动类或者配置类中,使用 @ComponentScan 注解指定 MyMetaObjectHandler 所在的包:

Maven多模块项目:MyBatis Plus 自动填充日期失效排查与解决
@SpringBootApplication
@ComponentScan({"com.example.common", "com.example.dao", "com.example.service", "com.example.web"})
public class WebApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class, args);
    }
}

或者,在 common-module 的 Spring Boot 启动类上使用 @EnableAutoConfiguration@ComponentScan,并确保 dao-module 和其他模块依赖 common-module

  1. 避免配置类冲突

只在一个模块中配置 MyBatis Plus 的相关配置,例如在 dao-module 中。避免在多个模块中使用 @MapperScan 注解。如果需要在多个模块中使用 Mapper,可以将 Mapper 接口定义在 dao-module 中,并在其他模块中引用。

Maven多模块项目:MyBatis Plus 自动填充日期失效排查与解决
@Configuration
@MapperScan("com.example.dao.mapper") // 只在 dao-module 中配置
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}
  1. 确保事务管理正确

使用 @Transactional 注解将 insertupdate 操作纳入事务管理。如果涉及到多个数据源或分布式事务,需要使用相应的事务管理器。

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Transactional
    @Override
    public void saveUser(User user) {
        userMapper.insert(user);
    }
}
  1. 检查模块依赖关系

确保 web-module 依赖 service-moduleservice-module 依赖 dao-moduledao-module 依赖 common-module。在 pom.xml 文件中明确声明依赖关系,避免循环依赖。

<!-- web-module 的 pom.xml -->
<dependencies>
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>service-module</artifactId>
        <version>${project.version}</version>
    </dependency>
</dependencies>
<!-- service-module 的 pom.xml -->
<dependencies>
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>dao-module</artifactId>
        <version>${project.version}</version>
    </dependency>
</dependencies>
<!-- dao-module 的 pom.xml -->
<dependencies>
    <dependency>
        <groupId>com.example</groupId>
        <artifactId>common-module</artifactId>
        <version>${project.version}</version>
    </dependency>
    <!-- MyBatis Plus 依赖 -->
     <dependency>
         <groupId>com.baomidou</groupId>
         <artifactId>mybatis-plus-boot-starter</artifactId>
         <version>3.5.3.1</version>
     </dependency>
</dependencies>
  1. 配置 MyMetaObjectHandler
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
        this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
    }
}

实战避坑经验总结

  1. 仔细检查包扫描路径:这是最常见的原因,也是最容易被忽略的。确保 Spring Boot 能够扫描到 MyMetaObjectHandler
  2. 避免重复配置:在多模块项目中,尽量将配置集中在一个模块中,避免在多个模块中重复配置。
  3. 明确模块依赖关系:确保模块之间的依赖关系正确,避免循环依赖。可以使用 Maven 的 dependency:tree 命令来查看依赖树。
  4. 打印日志调试:在 MyMetaObjectHandlerinsertFillupdateFill 方法中添加日志输出,方便调试。
  5. 升级 MyBatis Plus 版本:如果使用的 MyBatis Plus 版本较低,可能会存在一些 Bug。尝试升级到最新版本。
  6. 仔细阅读官方文档:MyBatis Plus 的官方文档非常详细,遇到问题时可以查阅官方文档。

总之,解决 Maven多模块项目MyMetaObjectHandler自动填充日期未生效 的问题需要仔细分析,逐一排查。希望本文能够帮助到遇到类似问题的同学。

Maven多模块项目:MyBatis Plus 自动填充日期失效排查与解决

转载请注明出处: 代码一只喵

本文的链接地址: http://m.acea3.store/blog/080147.SHTML

本文最后 发布于2026-04-07 13:17:41,已经过了20天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 四川担担面 4 天前
    说的很对,包扫描路径确实是个坑,特别是用到第三方组件的时候,更容易出问题。