使用mybatis-generator-maven-plugin生成的实体会自动覆盖rootClass定义的字段

问题描述

使用mybatis作为dao层的框架时,常常会使用mybatis-generator生成数据库实体类和mapper文件,这其中由于公司的项目规范,往往会在每张表里设置一些通用字段,这个时候就会用到rootClass,将这些通用的字段封装到其中,而生成的实体类自动继承rootClass定义的类,并且不会重写rootClass中已经存在的属性。

定义如下:

<javaModelGenerator targetPackage="com.gambo.guangjin.convert.dao.model" targetProject="src/main/java">
     <property name="rootClass" value="com.gambo.guangjin.convert.dao.model.BaseDO"/>
     <property name="suppressGeneratedAnnotations" value="true" />
</javaModelGenerator>
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources" />
<javaClientGenerator type="XMLMAPPER" targetPackage="com.gambo.guangjin.convert.dao.mapper" targetProject="src/main/java" />

<table tableName="convert_job"
       enableCountByExample="false"
       enableDeleteByExample="false"
       enableSelectByExample="false"
       enableUpdateByExample="false"
       domainObjectName="ConvertJobDO"
       mapperName="ConvertJobMapper"
/>

BaseDO的定义如下:

public class BaseDO {

    private Integer id;

    private Boolean deleted;

    private Date createdAt;

    private String createdBy;

    private Date updatedAt;

    private String updatedBy;

    public final  Integer getId() {
        return id;
    }

    public final  void setId(Integer id) {
        this.id = id;
    }

    public final  Boolean getDeleted() {
        return deleted;
    }

    public final  void setDeleted(Boolean deleted) {
        this.deleted = deleted;
    }

    public final  Date getCreatedAt() {
        return createdAt;
    }

    public final  void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }

    public final  String getCreatedBy() {
        return createdBy;
    }

    public final  void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }

    public final  Date getUpdatedAt() {
        return updatedAt;
    }

    public final  void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }

    public final  String getUpdatedBy() {
        return updatedBy;
    }

    public final  void setUpdatedBy(String updatedBy) {
        this.updatedBy = updatedBy;
    }
}

maven插件的定义如下:

<plugin>
   <groupId>org.mybatis.generator</groupId>
   <artifactId>mybatis-generator-maven-plugin</artifactId>
   <version>1.4.2</version>
   <configuration>
       <verbose>true</verbose>
       <overwrite>true</overwrite>                     
       <configurationFile>
        ${project.basedir}/src/main/resources/generatorConfig.xml
       </configurationFile>
   </configuration>
</plugin>

运行插件后生成的实体类,确实继承了BaseDO,但是事与愿违,其生成的属性重写了rootClass中国定义的字段,遇到这种问题无非是每次生成的实体类手动处理一下,很少有人会寻根究底,然而对于有强迫症的我很难咽的下这口气。


问题排查

生成代码的日志如下

注意这一句
 [WARNING] Root class com.gambo.guangjin.convert.dao.model.BaseDO cannot be loaded, checking for member overrides is disabled for this class
也就是说rootClass定义的类并没有被加载

调试mybatis-generator-core的源码确实如此

        for (ClassLoader classLoader : externalClassLoaders) {
            try {
                clazz = Class.forName(type, true, classLoader);
                return clazz;
            } catch (Exception e) {
                // ignore - fail safe below
            }
        }

以上代码出现了classNotFoundException,这种问题一般都考虑classPath的问题,也就是说在idea中运行maven插件并不会直接加载项目默认的classPath,这个时候如果引用了项目中的class就会出现这种情况。

解决方案

我们观察到,使用mybaits-generator时需要定义数据库驱动包所在的位置:

<classPathEntry location="F:\repository\org\postgresql\postgresql\42.7.4\postgresql-42.7.4.jar" />

查询了一下官方文档 这里的classPathEntry是可以重复定义的,从而引入多个外部classPath,这里我们可以把我们项目的默认路径作为classPathEntry定义。

由于mybatis-generator的实现方案时使用class.forName反射获取rootClass中的属性,所以这里需要填写项目编译后的class路径


添加如下配置

<classPathEntry location="./target/classes" />
此时再运行插件生成的实体类则不会重写rootClass中的属性。

总结

使用编程的方式调用mybatis-generator-core的功能生成代码则不会出现上面的问题,因为在idea中运行代码的时候会先自动进行编译,生成target/class目录以及编译后的文件,并且自动加载其中的class,但是用插件的方式则需要先编译成功后在添加./target/classes的classPath到generatorConfig.xml中.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值