一、MyBatis Plus Generator
MyBatis Plus
是一个功能强大的持久层框架,它简化了MyBatis
的使用,提供了许多便捷的功能。其中,MyBatis Plus Generator
是一个强大的代码生成器,可以帮助我们快速地根据数据库表结构生成对应的实体类、映射文件和DAO接口。在MyBatis Plus Generator
中,我们可以使用模板ftl文件来自定义生成的代码样式。本文将介绍如何使用MyBatis Plus Generator
通过模板ftl文件生成代码。
二、使用介绍
2.1 引入依赖
<!--mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-annotation</artifactId><version>3.4.1</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.4.1</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version><exclusions><exclusion><groupId>io.swagger</groupId><artifactId>swagger-annotations</artifactId></exclusion><exclusion><groupId>io.swagger</groupId><artifactId>swagger-models</artifactId></exclusion></exclusions></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency><dependency><groupId>io.swagger</groupId><artifactId>swagger-annotations</artifactId><version>1.5.21</version></dependency><dependency><groupId>io.swagger</groupId><artifactId>swagger-models</artifactId><version>1.5.21</version></dependency>
2.2 模版文件
在项目的resources
文件夹下创建一个名为templates
的文件夹,用于存放模板ftl
文件。
2.2.1 controller.java.ftl
package ${package.Controller};import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
<#if restControllerStyle>
import org.springframework.web.bind.annotation.RestController;
<#else>
import org.springframework.stereotype.Controller;
</#if>
<#if swagger2>
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
</#if>
<#if superControllerClassPackage??>
import ${superControllerClassPackage};
</#if>
import ${package.Service}.${table.serviceName};/*** @author ${author}* @description ${table.comment!}前端控制器* @date ${date}*/
<#if swagger2>
@Api(tags = "${table.comment!}前端控制器")
</#if>
<#if restControllerStyle>
@RestController
<#else>
@Controller
</#if>
@RequestMapping("<#if package.ModuleName?? && package.ModuleName != "">/${package.ModuleName}</#if>/<#if controllerMappingHyphenStyle??>${controllerMappingHyphen}<#else>${table.entityPath}</#if>")
<#if kotlin>
class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}()</#if>
<#else>
<#if superControllerClass??>
public class ${table.controllerName} extends ${superControllerClass} {
<#else>
public class ${table.controllerName} {
</#if>@Resourceprivate ${table.serviceName} ${table.entityPath}Service;@ApiOperation(value = "按id查询")@GetMapping("/single")public ResultBean<${entity}VO> queryById(Long id) {return ResultBean.success(${table.entityPath}Service.queryById(id));}@ApiOperation(value = "按id删除")@PostMapping("/delete/single")public ResultBean deleteById(Long id) {${table.entityPath}Service.deleteById(id);return ResultBean.success();}@ApiOperation(value = "按id更新")@PostMapping("/update/single")public ResultBean<${entity}VO> update(@RequestBody ${entity}VO vo) {vo = ${table.entityPath}Service.update(vo);return ResultBean.success(vo);}@ApiOperation(value = "新增")@PostMapping("/insert/single")public ResultBean<${entity}VO> insert(@RequestBody ${entity}VO vo) {vo = ${table.entityPath}Service.insert(vo);return ResultBean.success(vo);}}
</#if>
2.2.2 dto.java.ftl
package ${cfg.packageParent}.DTO;<#list table.importPackages as pkg><#if !(pkg?contains('mybatis') || pkg?contains('entity'))><#if pkg == 'java.time.LocalDateTime'>import java.util.Date;<#else >import ${pkg};</#if></#if>
</#list>
import java.io.Serializable;
<#if swagger2>import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;
</#if><#if entityLombokModel>import lombok.Data;import lombok.EqualsAndHashCode;<#if chainModel>import lombok.experimental.Accessors;</#if>
</#if>/*** @author ${author}* @description ${table.comment!}VO* @date ${date}*/
<#if entityLombokModel>
@Data
<#--@EqualsAndHashCode(callSuper = false)-->
<#--@Accessors(chain = true)-->
</#if>
<#if swagger2>
@ApiModel(value = "${entity}DTO对象", description = "${table.comment!} DTO")
</#if>
public class ${entity}DTO implements Serializable {private static final long serialVersionUID = 1L;
<#list table.fields as field><#if field.comment!?length gt 0><#if swagger2>/*** ${field.comment}*/@ApiModelProperty(value = "${field.comment}")<#else>/*** ${field.comment}*/</#if></#if><#if field.propertyType == 'LocalDateTime'>@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")private LocalDateTime ${field.propertyName};<#else>private ${field.propertyType} ${field.propertyName};</#if>
</#list>
<#------------ END 字段循环遍历 ---------->
<#if !entityLombokModel><#list table.fields as field><#if field.propertyType == "boolean"><#assign getprefix="is"/><#else><#assign getprefix="get"/></#if><#if field.propertyType == "LocalDateTime"><#assign betterPropertyType="Date"/><#else><#assign betterPropertyType="${field.propertyType}"/></#if>public ${betterPropertyType} ${getprefix}${field.capitalName}() {return ${field.propertyName};}<#if chainModel>public ${entity} set${field.capitalName}(${betterPropertyType} ${field.propertyName}) {<#else>public void set${field.capitalName}(${betterPropertyType} ${field.propertyName}) {</#if>this.${field.propertyName} = ${field.propertyName};<#if chainModel>return this;</#if>}</#list>
</#if>
<#if !entityLombokModel>@Overridepublic String toString() {return "${entity}{" +<#list table.commonFields as field><#if field_index==0>"${field.propertyName}=" + ${field.propertyName} +<#else>", ${field.propertyName}=" + ${field.propertyName} +</#if></#list><#list table.fields as field><#if field_index==0>"${field.propertyName}=" + ${field.propertyName} +<#else>", ${field.propertyName}=" + ${field.propertyName} +</#if></#list>"}";}
</#if>
}
2.2.3 entity.java.ftl
package ${package.Entity};<#list table.importPackages as pkg>
<#if pkg == 'java.time.LocalDateTime'>
import java.util.Date;
<#else >
import ${pkg};
</#if>
</#list>
<#if swagger2>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel>
import lombok.Data;
import lombok.EqualsAndHashCode;<#if chainModel>
import lombok.experimental.Accessors;</#if>
</#if>/**
* @author ${author}
* @description ${table.comment!}实体
* @date ${date}
*/
<#if entityLombokModel>
@Data<#if superEntityClass??>
@EqualsAndHashCode(callSuper = true)<#else>
@EqualsAndHashCode(callSuper = false)</#if>
<#-- <#if chainModel>-->
<#--@Accessors(chain = true)-->
<#-- </#if>-->
</#if>
<#if table.convert>
@TableName("${table.name}")
</#if>
<#if swagger2>
@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}> {
<#else>
public class ${entity} implements Serializable {
</#if><#if entitySerialVersionUID>private static final long serialVersionUID = 1L;
</#if>
<#-- ---------- BEGIN 字段循环遍历 ---------->
<#list table.fields as field><#if field.keyFlag><#assign keyPropertyName="${field.propertyName}"/></#if><#if field.comment!?length gt 0><#if swagger2>/*** ${field.comment}*/@ApiModelProperty(value = "${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 (versionFieldName!"") == field.name>@Version</#if><#-- 逻辑删除注解 --><#if (logicDeleteFieldName!"") == field.name>@TableLogic</#if><#if field.propertyType == 'LocalDateTime'>private Date ${field.propertyName};<#else>private ${field.propertyType} ${field.propertyName};</#if>
</#list>
<#------------ END 字段循环遍历 ---------->
<#if !entityLombokModel><#list table.fields as field><#if field.propertyType == "boolean"><#assign getprefix="is"/><#else><#assign getprefix="get"/></#if><#if field.propertyType == "LocalDateTime"><#assign betterPropertyType="Date"/><#else><#assign betterPropertyType="${field.propertyType}"/></#if>public ${betterPropertyType} ${getprefix}${field.capitalName}() {return ${field.propertyName};}<#if chainModel>public ${entity} set${field.capitalName}(${betterPropertyType} ${field.propertyName}) {<#else>public void set${field.capitalName}(${betterPropertyType} ${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>@Overrideprotected Serializable pkVal() {<#if keyPropertyName??>return this.${keyPropertyName};<#else>return null;</#if>}</#if>
<#if !entityLombokModel>@Overridepublic 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>
}
2.2.4 mapper.java.ftl
package ${package.Mapper};<#--import ${package.Entity}.${entity};-->
import ${superMapperClassPackage};
<#--import ${cfg.packageParent}.vo.${entity}VO;-->
import java.util.List;import javax.validation.constraints.NotNull;/*** @author ${author}* @description ${table.comment!} Mapper 接口* @date ${date}*/
<#if kotlin>
interface ${table.mapperName} : ${superMapperClass}<${entity}>
<#else>
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {List<${entity}> queryByCondition(@NotNull ${entity}VO condition);
}
</#if>
2.2.5 mapper.xml.ftl
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper}.mybatis.mapper.${table.mapperName}"><#if enableCache><!-- 开启二级缓存 --><cache type="org.mybatis.caches.ehcache.LoggingEhcache"/></#if><#if baseResultMap><!-- 通用查询映射结果 --><resultMap id="BaseResultMap" type="${package.Entity}.mybatis.entity.${entity}"><#list table.fields as field><#if field.keyFlag><#--生成主键排在第一位--><id column="${field.name}" property="${field.propertyName}"/></#if></#list><#list table.commonFields as field><#--生成公共字段 --><result column="${field.name}" property="${field.propertyName}"/></#list><#list table.fields as field><#if !field.keyFlag><#--生成普通字段 --><result column="${field.name}" property="${field.propertyName}"/></#if></#list></resultMap></#if><#if baseColumnList><!-- 通用查询结果列 --><sql id="Base_Column_List"><#list table.commonFields as field>${field.columnName},</#list>${table.fieldNames}</sql></#if><select id="queryByCondition" resultMap="BaseResultMap" parameterType="${cfg.packageParent}.dto.${entity}VO">SELECT<include refid="Base_Column_List"/>FROM ${table.name}<where><#list table.commonFields as field><#--生成公共字段 --><#if field.propertyType == 'String'><if test="${field.propertyName} != null and ${field.propertyName} != ''"><#else><if test="${field.propertyName} != null"></#if><#if field.propertyType == 'String'>AND ${field.annotationColumnName} LIKE CONCAT('%', ${"#{"}${field.propertyName}${"}"}, '%')<#else>AND ${field.annotationColumnName} = ${"#{"}${field.propertyName}${"}"}</#if></if></#list><#list table.fields as field><#if field.propertyType == 'String'><if test="${field.propertyName} != null and ${field.propertyName} != ''"><#else><#if field.propertyType == 'String'><if test="${field.propertyName} != null and ${field.propertyName} != ''"><#else><if test="${field.propertyName} != null"></#if></#if><#if field.propertyType == 'String'>AND ${field.annotationColumnName} LIKE CONCAT('%', ${"#{"}${field.propertyName}${"}"}, '%')<#else>AND ${field.annotationColumnName} = ${"#{"}${field.propertyName}${"}"}</#if></if></#list></where></select>
</mapper>
2.2.6 service.java.ftl
package ${package.Service};import ${superServiceClassPackage};/*** @author ${author}* @description ${table.comment!}服务类* @date ${date}*/
<#if kotlin>interface ${table.serviceName} : ${superServiceClass}<${entity}>
<#else>
public interface ${table.serviceName} {${entity}DTO queryById(Long id);${entity}DTO update(${entity}DTO dto);${entity}DTO insert(${entity}DTO dto);void deleteById(Long id);}
</#if>
2.2.7 serviceImpl.java.ftl
package ${package.ServiceImpl};import java.util.List;
import java.util.ArrayList;
import javax.validation.constraints.NotNull;import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};import org.springframework.stereotype.Service;
import org.springframework.beans.BeanUtils;
import javax.annotation.Resource;/*** @author ${author}* @description ${table.comment!} 服务实现类* @date ${date}*/
@Service
<#if kotlin>
open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {}
<#else>
public class ${table.serviceImplName} extends ServiceImpl<${table.mapperName}, ${entity}> implements ${table.serviceName} {@Resourceprivate ${table.mapperName} ${table.entityPath}Mapper;private List<${entity}DTO> toDTOList(@NotNull List<${entity}> entities) {List<${entity}DTO> dtoList = new ArrayList<>(entities.size());for (${entity} entity : entities) {dtoList.add(toDTO(entity));}return dtoList;}private ${entity}DTO toDTO(@NotNull ${entity} entity) {${entity}DTO dto = new ${entity}DTO();BeanUtils.copyProperties(entity, dto);return dto;}@Overridepublic ${entity}DTO queryById(@NotNull Long id) {${entity} entity = ${table.entityPath}Mapper.selectById(id);return toDTO(entity);}@Overridepublic ${entity}DTO update(@NotNull ${entity}DTO dto) {${entity} entity = ${table.entityPath}Mapper.selectById(dto.getId());if (entity == null) {// 不存在return null;}BeanUtils.copyProperties(dto, entity, "id");${table.entityPath}Mapper.updateById(entity);return dto;}@Overridepublic ${entity}DTO insert(@NotNull ${entity}DTO dto) {${entity} entity = new ${entity}();BeanUtils.copyProperties(dto, entity, "id");${table.entityPath}Mapper.insert(entity);return toDTO(entity);}@Overridepublic void deleteById(@NotNull Long id) {${table.entityPath}Mapper.deleteById(id);}
}
</#if>
2.3 Swagger
配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;/*** @author Jerryean* @description swagger配置类* @date 2024/3/13**/
@Configuration
@EnableSwagger2
public class SwaggerConfig {@Beanpublic Docket docket() {return new Docket(DocumentationType.SWAGGER_2).enable(true).apiInfo(apiInfo()).groupName("默认")
// .pathMapping("/test/api/web").select().apis(RequestHandlerSelectors.basePackage("com.test.web.controller")).paths(PathSelectors.any()).build();}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("接口文档").description("接口文档").version("1.0").build();}
}
2.4 Generator
逻辑
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import lombok.extern.slf4j.Slf4j;import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @author Jerryean* @date 2023/6/14*/
@Slf4j
public class CodeGenerator {static String entityDir;static String voDir;static String mapperDir;static String mapperXmlDir;static String serviceDir;static String controllerDir;static String serviceImplDir;// 生成路径static final String PRO_PATH = "D:\\companyCode\\";static final String CODE_PATH = "D:\\companyCode\\code\\";static final String XML_PATH = "D:\\companyCode\\mapper\\";static final String OPEN_DIR = "D:\\companyCode\\";// 是否覆盖static final boolean override = true;// 父类包static final String parentPkg = "com.cisdi";static final String author = "Jerryean";// 模板路径static final String templatePath = "/templates";// 生成的表static final String[] dataTables = {"student", "teacher"};private static class DataBaseConfig {static final String url = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC";static final String username = "root";static final String password = "pwd123456";}public static void main(String[] args) {// 代码生成器AutoGenerator autoGenerator = new AutoGenerator();// 初始化输出文件夹init();// 删除之前生成的数据if (override) {delDir();}// 全局配置configGlobal(autoGenerator);// pkg设置configPkg(autoGenerator);// 数据源配置DataSourceConfig dsc = new DataSourceConfig();dsc.setDbType(DbType.MYSQL);dsc.setUrl(DataBaseConfig.url);dsc.setSchemaName("public");dsc.setDriverName("com.mysql.cj.jdbc.Driver");dsc.setUsername(DataBaseConfig.username);dsc.setPassword(DataBaseConfig.password);autoGenerator.setDataSource(dsc);// 配置指定自定义模板参数和类型InjectionConfig cfg = new InjectionConfig() {@Overridepublic void initMap() {Map<String, Object> map = new HashMap<>();map.put("baseResultMap", true);map.put("packageParent", parentPkg);this.setMap(map);}};List<FileOutConfig> focList = new ArrayList<>();importTemplate(focList);cfg.setFileOutConfigList(focList);autoGenerator.setCfg(cfg);// 配置策略StrategyConfig strategyConfig = new StrategyConfig();strategyConfig.setEntityLombokModel(true);// 包含的表strategyConfig.setInclude(dataTables);strategyConfig.setNaming(NamingStrategy.underline_to_camel);strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);strategyConfig.setRestControllerStyle(true);autoGenerator.setStrategy(strategyConfig);// 配置模板configTemplate(autoGenerator);// 执行autoGenerator.execute();//执行完之后打开try {// 要打开的文件夹路径File folder = new File(OPEN_DIR);// 打开文件夹Desktop.getDesktop().open(folder);} catch (IOException ignored) {}}static void init() {entityDir = CodeGenerator.CODE_PATH + "/entity";voDir = CodeGenerator.CODE_PATH + "/dto";mapperDir = CodeGenerator.CODE_PATH + "/mapper";mapperXmlDir = CodeGenerator.XML_PATH;serviceDir = CodeGenerator.CODE_PATH + "/service";serviceImplDir = CodeGenerator.CODE_PATH + "/service/impl";controllerDir = CodeGenerator.CODE_PATH + "/controller";}static void delDir() {List<String> dirs = new ArrayList<>();dirs.add(entityDir);dirs.add(voDir);dirs.add(mapperDir);dirs.add(mapperXmlDir);dirs.add(serviceDir);dirs.add(serviceImplDir);dirs.add(controllerDir);for (String per : dirs) {if (FileUtil.exist(per)) {FileUtil.del(per);} else {log.warn("no dir{}", per);}}}static void importTemplate(List<FileOutConfig> focList) {String entityTemplatePath = CodeGenerator.templatePath + "/entity.java.ftl";String mapperTemplatePath = CodeGenerator.templatePath + "/mapper.java.ftl";String mapperXmlTemplatePath = CodeGenerator.templatePath + "/mapper.xml.ftl";String voTemplatePath = CodeGenerator.templatePath + "/dto.java.ftl";String controllerTemplatePath = CodeGenerator.templatePath + "/controller.java.ftl";String serviceTemplatePath = CodeGenerator.templatePath + "/service.java.ftl";String serviceImplTemplatePath = CodeGenerator.templatePath + "/serviceImpl.java.ftl";// 自定义输出配置// 自定义配置会被优先输出focList.add(new FileOutConfig(entityTemplatePath) {@Overridepublic String outputFile(TableInfo tableInfo) {// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!return entityDir+ "/" + tableInfo.getEntityName() + ".java";}});focList.add(new FileOutConfig(mapperTemplatePath) {@Overridepublic String outputFile(TableInfo tableInfo) {// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!return mapperDir+ "/" + tableInfo.getEntityName() + "Mapper.java";}});focList.add(new FileOutConfig(mapperXmlTemplatePath) {@Overridepublic String outputFile(TableInfo tableInfo) {// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!return mapperXmlDir+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;}});focList.add(new FileOutConfig(voTemplatePath) {@Overridepublic String outputFile(TableInfo tableInfo) {// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!return voDir+ "/" + tableInfo.getEntityName() + "DTO.java";}});focList.add(new FileOutConfig(controllerTemplatePath) {@Overridepublic String outputFile(TableInfo tableInfo) {// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!return controllerDir+ "/" + tableInfo.getEntityName() + "Controller.java";}});focList.add(new FileOutConfig(serviceTemplatePath) {@Overridepublic String outputFile(TableInfo tableInfo) {// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!return serviceDir+ "/" + tableInfo.getEntityName() + "Service.java";}});focList.add(new FileOutConfig(serviceImplTemplatePath) {@Overridepublic String outputFile(TableInfo tableInfo) {// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!return serviceImplDir+ "/" + tableInfo.getEntityName() + "ServiceImpl.java";}});}private static void configGlobal(AutoGenerator autoGenerator) {// 全局配置GlobalConfig gc = new GlobalConfig();gc.setOutputDir(CodeGenerator.PRO_PATH + "/src/main/java");gc.setAuthor(CodeGenerator.author);gc.setOpen(false);gc.setSwagger2(true);gc.setBaseResultMap(true);gc.setBaseColumnList(true);gc.setServiceName("%s" + ConstVal.SERVICE);autoGenerator.setGlobalConfig(gc);}private static void configPkg(AutoGenerator autoGenerator) {PackageConfig packageConfig = new PackageConfig();packageConfig.setParent(parentPkg);packageConfig.setController("controller");packageConfig.setService("service");packageConfig.setServiceImpl("service.impl");packageConfig.setMapper("mapper");packageConfig.setEntity("entity");autoGenerator.setPackageInfo(packageConfig);}private static void configTemplate(AutoGenerator autoGenerator) {TemplateConfig templateConfig = new TemplateConfig();// 只使用前面的自定义生成模板templateConfig.setController("");templateConfig.setService("");templateConfig.setServiceImpl("");templateConfig.setEntity("");templateConfig.setMapper("");templateConfig.setXml(null);autoGenerator.setTemplate(templateConfig);autoGenerator.setTemplateEngine(new FreemarkerTemplateEngine());}}
三、总结
MyBatis-Plus使用FTL模板能高效自动生成规范易读的代码,支持灵活定制和多平台,降低维护成本,提高开发效率。以上生成代码所用的逻辑,欢迎大家可以取下来使用。