likes
comments
collection
share

【Java】mybatis-plus-generator新版代码自动生成器依赖的使用

作者站长头像
站长
· 阅读数 16

为了减少手动造轮子的次数,开始尝试使用代码生成器(代码生成脚本)的方式初始化简单的代码逻辑。

引入依赖

这边以maven项目为例,修改项目pom文件。

<!-- mybatis-plus -->
<dependency>
   <groupId>com.baomidou</groupId>
   <artifactId>mybatis-plus-boot-starter</artifactId>
   <version>3.5.4</version>
</dependency>
<!-- mysql驱动包 -->
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <scope>runtime</scope>
</dependency>

<!-- 代码自动生成器依赖 -->
<dependency>
   <groupId>com.baomidou</groupId>
   <artifactId>mybatis-plus-generator</artifactId>
   <version>3.5.4</version>
</dependency>
<!-- 模板引擎 默认的模板引擎是velocity,这边使用的是freemarker -->
<dependency>
   <groupId>org.apache.velocity</groupId>
   <artifactId>velocity-engine-core</artifactId>
   <version>2.2</version>
</dependency>
<dependency>
   <groupId>org.freemarker</groupId>
   <artifactId>freemarker</artifactId>
   <version>2.3.31</version>
</dependency>

注意各个依赖之间的版本号。

添加配置

在项目test路径下创建脚本。

public static void main(String[] args) {
    FastAutoGenerator.create("jdbc:mysql://localhost:3306/xxx?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&remarks=true&useInformationSchema=true","root","root")
            .globalConfig(builder -> {
                builder.author("author") // 设置作者
                        .enableSwagger() // 开启 swagger 模式
                        .fileOverride() // 覆盖已生成文件
                        .commentDate("yyyy-MM-dd")
                        .outputDir(System.getProperty("user.dir")+"\src\main\java"); // 指定输出目录
            })
            .dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
                int typeCode = metaInfo.getJdbcType().TYPE_CODE;
                if (typeCode == Types.SMALLINT) {
                    // 自定义类型转换
                    return DbColumnType.INTEGER;
                }
                return typeRegistry.getColumnType(metaInfo);

            }))
            .packageConfig(builder -> {
                builder.parent("com.xxx") // 设置父包名
                        .moduleName("generator") // 设置父包模块名
                        .entity("entity")
                        .service("service")
                        .serviceImpl("service.impl")
                        .controller("controller")
                        .mapper("mapper")
                        .xml("mapper")
                        .pathInfo(Collections.singletonMap(OutputFile.xml, System.getProperty("user.dir")+"\src\main\resources\mapper")); // 设置mapperXml生成路径
            })
            .strategyConfig(builder -> {
                builder.addInclude("table_name") // 设置需要生成的表名
                        .addTablePrefix("t_", "c_") // 设置过滤表前缀
                        .entityBuilder()
                        .superClass("com.xxx.dao.common.entity.BaseEntity")
                        .serviceBuilder()
                        .formatServiceFileName("%sService")
                        .formatServiceImplFileName("%sServiceImpl")
                        .entityBuilder()
                        .enableLombok()
                        .logicDeleteColumnName("deleted")
                        .enableTableFieldAnnotation()
                        .controllerBuilder()
                        // 映射路径使用连字符格式,而不是驼峰
                        .enableHyphenStyle()
                        .formatFileName("%sController")
                        .enableRestStyle()
                        .mapperBuilder()
                        //生成通用的resultMap
                        .enableBaseResultMap()
                        .superClass(BaseMapper.class)
                        .formatMapperFileName("%sMapper")
                        .enableMapperAnnotation()
                        .formatXmlFileName("%sMapper");
            })
            .templateConfig(config->{
                config.disable(TemplateType.ENTITY)
                        .entity("/templates/entity.java")
                        .build();
            })
            .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
            .execute();
}

自定义导出模板

上述配置文件末尾指定了entity使用resource/templates路径下的entity.java.ftl模板。

.templateConfig(config->{
    config.disable(TemplateType.ENTITY)
            .entity("/templates/entity.java")
            .build();
})

一般来说项目会规定一些固定的字段,使用父类的方式提供给子实体类进行继承,避免重复代码。因此我们自动生成的实体类中也必须包含。需要提前在配置类中进行父类的位置的配置。

.entityBuilder()
.superClass("com.xxx.dao.common.entity.BaseEntity")

接下来就是entity.java.ftl模板的内容:

package ${package.Entity};
<#-------  使用freemarker的语法进行创建变量,不支持直接从superEntityClass中直接遍历字段结果  ------>
<#assign list=["createBy","createTime", "updateBy", "updateTime", "remark"]>
<#list table.importPackages as pkg>
import ${pkg};
</#list>
<#if springdoc>
import io.swagger.v3.oas.annotations.media.Schema;
<#elseif swagger>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel>
import lombok.Getter;
import lombok.Setter;
    <#if chainModel>
import lombok.experimental.Accessors;
    </#if>
</#if>

/**
 * <p>
 * ${table.comment!}
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
<#if entityLombokModel>
@Getter
@Setter
    <#if chainModel>
@Accessors(chain = true)
    </#if>
</#if>
<#if table.convert>
@TableName("${schemaName}${table.name}")
</#if>
<#if springdoc>
@Schema(name = "${entity}", description = "${table.comment!}")
<#elseif swagger>
@ApiModel(value = "${entity}对象", description = "${table.comment!}")
</#if>
<#if superEntityClass??>
public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}></#if> {
<#elseif activeRecord>
public class ${entity} extends Model<${entity}> {
<#elseif entitySerialVersionUID>
public class ${entity} implements Serializable {
<#else>
public class ${entity} {
</#if>
<#if entitySerialVersionUID>

    private static final long serialVersionUID = 1L;
</#if>
<#-- ----------  BEGIN 字段循环遍历  ---------->
<#list table.fields as field>
    <#-- ---------- 判断父类是否存在 ---------->
    <#if superEntityClass??>
        <#-- ----------  判断当前字段在父类中是否存在,存在即跳过  ---------->
        <#if list?seq_contains("${field.propertyName}")>
            <#continue>
        </#if>
    </#if>
    <#if field.keyFlag>
        <#assign keyPropertyName="${field.propertyName}"/>
    </#if>

    <#if field.comment!?length gt 0>
        <#if springdoc>
    @Schema(description = "${field.comment}")
        <#elseif swagger>
    @ApiModelProperty("${field.comment}")
        <#else>
    /**
     * ${field.comment}
     */
        </#if>
    </#if>
    <#if field.keyFlag>
        <#-- 主键 -->
        <#if field.keyIdentityFlag>
    @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
        <#elseif idType??>
    @TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
        <#elseif field.convert>
    @TableId("${field.annotationColumnName}")
        </#if>
        <#-- 普通字段 -->
    <#elseif field.fill??>
    <#-- -----   存在字段填充设置   ----->
        <#if field.convert>
    @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
        <#else>
    @TableField(fill = FieldFill.${field.fill})
        </#if>
    <#elseif field.convert>
    @TableField("${field.annotationColumnName}")
    </#if>
    <#-- 乐观锁注解 -->
    <#if field.versionField>
    @Version
    </#if>
    <#-- 逻辑删除注解 -->
    <#if field.logicDeleteField>
    @TableLogic
    </#if>
    private ${field.propertyType} ${field.propertyName};
</#list>
<#------------  END 字段循环遍历  ---------->
<#if !entityLombokModel>
    <#list table.fields as field>
        <#if field.propertyType == "boolean">
            <#assign getprefix="is"/>
        <#else>
            <#assign getprefix="get"/>
        </#if>

    public ${field.propertyType} ${getprefix}${field.capitalName}() {
        return ${field.propertyName};
    }

    <#if chainModel>
    public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
    <#else>
    public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
    </#if>
        this.${field.propertyName} = ${field.propertyName};
        <#if chainModel>
        return this;
        </#if>
    }
    </#list>
</#if>
<#if entityColumnConstant>
    <#list table.fields as field>

    public static final String ${field.name?upper_case} = "${field.name}";
    </#list>
</#if>
<#if activeRecord>

    @Override
    public Serializable pkVal() {
    <#if keyPropertyName??>
        return this.${keyPropertyName};
    <#else>
        return null;
    </#if>
    }
</#if>
<#if !entityLombokModel>

    @Override
    public String toString() {
        return "${entity}{" +
    <#list table.fields as field>
        <#if field_index==0>
            "${field.propertyName} = " + ${field.propertyName} +
        <#else>
            ", ${field.propertyName} = " + ${field.propertyName} +
        </#if>
    </#list>
        "}";
    }
</#if>
}

依照这种修改方式,可以推理到service以及controller等层次的模板修改。类似controller、service层添加一些常规的增删改查的方法,这样可以实现脚本执行后便可以直接启动一个相对基础的项目,无需自己动手操作。

mybatis-plus-generator插件支持生成的代码文件对本地进行覆盖,注意代码生成后需要进行git管理,以免覆盖了手写代码无法回滚。

转载自:https://juejin.cn/post/7295538198238494720
评论
请登录