一、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>
@Resource
private ${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>
@Override
public 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>
@Override
protected 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>
}
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} {
@Resource
private ${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;
}
@Override
public ${entity}DTO queryById(@NotNull Long id) {
${entity} entity = ${table.entityPath}Mapper.selectById(id);
return toDTO(entity);
}
@Override
public ${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;
}
@Override
public ${entity}DTO insert(@NotNull ${entity}DTO dto) {
${entity} entity = new ${entity}();
BeanUtils.copyProperties(dto, entity, "id");
${table.entityPath}Mapper.insert(entity);
return toDTO(entity);
}
@Override
public 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 {
@Bean
public 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() {
@Override
public 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) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return entityDir
+ "/" + tableInfo.getEntityName() + ".java";
}
});
focList.add(new FileOutConfig(mapperTemplatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return mapperDir
+ "/" + tableInfo.getEntityName() + "Mapper.java";
}
});
focList.add(new FileOutConfig(mapperXmlTemplatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return mapperXmlDir
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
focList.add(new FileOutConfig(voTemplatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return voDir
+ "/" + tableInfo.getEntityName() + "DTO.java";
}
});
focList.add(new FileOutConfig(controllerTemplatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return controllerDir
+ "/" + tableInfo.getEntityName() + "Controller.java";
}
});
focList.add(new FileOutConfig(serviceTemplatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return serviceDir
+ "/" + tableInfo.getEntityName() + "Service.java";
}
});
focList.add(new FileOutConfig(serviceImplTemplatePath) {
@Override
public 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模板能高效自动生成规范易读的代码,支持灵活定制和多平台,降低维护成本,提高开发效率。以上生成代码所用的逻辑,欢迎大家可以取下来使用。