【Java】mybatis-plus-generator新版代码自动生成器依赖的使用
为了减少手动造轮子的次数,开始尝试使用代码生成器(代码生成脚本)的方式初始化简单的代码逻辑。
引入依赖
这边以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