MyBatis Plus Generator代码生成

一、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模板能高效自动生成规范易读的代码,支持灵活定制和多平台,降低维护成本,提高开发效率。以上生成代码所用的逻辑,欢迎大家可以取下来使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/854854.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言中的预处理指令(如#include, #define等)是什么

C语言中的预处理指令是特殊的命令&#xff0c;它们在编译程序的实际编译阶段之前由预处理器&#xff08;preprocessor&#xff09;处理。这些指令用于在编译之前修改源代码&#xff0c;例如包含其他文件、定义常量或宏等。以下是C语言中常见的预处理指令&#xff1a; #include&…

Java基础-案例练习-全是干货

目录 案例&#xff1a;卖飞机票 案例&#xff1a;找质数&#xff1a; 案例&#xff1a;开发验证码 案例&#xff1a;评委打分 案例&#xff1a;卖飞机票 package anlixunlian;import java.util.Scanner;/*机票价格按照淡季旺季、头等舱和经济舱收费、 输入机票原价、月份和…

使用Ollama+OpenWebUI本地部署阿里通义千问Qwen2 AI大模型

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;AI大模型部署与应用专栏&#xff1a;点击&#xff01; &#x1f916;Ollama部署LLM专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年6月17日22点50分 &#x1f004;️文章质量&#xff…

探索设计模式——单例模式详解

前言&#xff1a;设计模式的作用主要是为了——利用设计方式的重用来自动地提高代码的重新利用、提高代码的灵活性、节省时间&#xff0c; 提高开发效率、低耦合&#xff0c;封装特性显著&#xff0c; 接口预留有利于扩展。 设计模式的种类有很多种&#xff0c;本篇内容主要讲解…

Git Stash的使用和进阶

git stash 是Git中一个非常实用的命令&#xff0c;它能帮助你暂时存储工作目录和索引&#xff08;也就是暂存区&#xff09;中的改动&#xff0c;从而让你可以轻松地切换到一个干净的工作状态&#xff0c;而不会丢失当前的进度。下面是关于git stash的一些基本用法和相关命令&a…

计算机网络5:运输层

概述 进程间基于网络的通信 计算机网络中实际进行通信的真正实体&#xff0c;是位于通信两端主机中的进程。 如何为运行在不同主机上的应用进程提供直接的逻辑通信服务&#xff0c;就是运输层的主要任务。运输层协议又称为端到端协议。 运输层向应用层实体屏蔽了下面网络核心…

【机器学习】机器学习重要分支——集成学习:理论、算法与实践

文章目录 引言第一章 集成学习的基本概念1.1 什么是集成学习1.2 集成学习的类型1.3 集成学习的优势 第二章 集成学习的核心算法2.1 Bagging方法2.2 Boosting方法2.3 Stacking方法 第三章 集成学习的应用实例3.1 图像分类3.2 文本分类 第四章 集成学习的未来发展与挑战4.1 模型多…

【前端项目笔记】2 主页布局

主页布局 element-ui提供的组件名称就是它的类名 ☆☆ CSS选择器&#xff1a; &#xff08;1&#xff09;基本选择器 类型选择器 p/span/div…… 类选择器 (.classname) ID选择器 (#idname) 通配选择器 ( * ) &#xff08;2&#xff09;属性选择器 选择具有特定属性或属性值的…

编程猫对孩子有什么用处:探索编程教育的多元价值

编程猫对孩子有什么用处&#xff1a;探索编程教育的多元价值 在数字化浪潮席卷全球的今天&#xff0c;编程教育逐渐成为了孩子们成长道路上不可或缺的一部分。编程猫&#xff0c;作为专注于儿童编程教育的品牌&#xff0c;以其独特的教学方式和丰富的教学内容&#xff0c;深受…

【C语言】解决C语言报错:Uninitialized Variable

文章目录 简介什么是Uninitialized VariableUninitialized Variable的常见原因如何检测和调试Uninitialized Variable解决Uninitialized Variable的最佳实践详细实例解析示例1&#xff1a;局部变量未初始化示例2&#xff1a;数组未初始化示例3&#xff1a;指针未初始化示例4&am…

C语言、C++和C#的区别在什么地方?

C语言、C和C#是三种不同的编程语言&#xff0c;它们在设计目标、特性和应用领域上有各自的特点。C语言是一种过程式编程语言&#xff0c;C是一种多范式编程语言&#xff0c;支持过程式编程和面向对象编程&#xff0c;而C#是一种高级的面向对象编程语言&#xff0c;主要面向.NET…

C的I/O操作

目录 引言 一、文件与目录操作 1. 打开与关闭文件 2. 文件读写操作 3. 文件定位与错误处理 二、字符流与字节流 1. 字符流处理 2. 字节流处理 三、序列化与反序列化 1. 序列化 2. 反序列化 四、新的I/O&#xff08;NIO&#xff09; 表格总结 文件与目录操作 字符…

## Java注解深入解析:增强代码可读性和维护性

Java注解是一个元数据形式&#xff0c;提供了一种用于在代码中添加信息的方法&#xff0c;这些信息可以通过编译时的处理工具或运行时的处理过程来使用。注解使得程序员可以写出更干净、更易于理解和维护的代码。本文将介绍Java注解的基本概念、创建自定义注解、以及注解在实际…

Java基础学习-数组

目录 数组定义 注意点&#xff1a; 地址值是数组在内存中实际存储的地址。 案例遍历&#xff1a;遍历数组得到每一个元素&#xff0c;求数组里面所有数据和 案例&#xff1a;定义数组&#xff0c;遍历能被3整除的数字 案例&#xff1a;遍历一个数组&#xff0c;奇数将当前…

守护电力心脏:国网电力监控运维平台的智慧使命

国网电力监控运维平台&#xff0c;以其强大的数据分析和处理能力&#xff0c;实现了对电网运行的实时监控。无论是电压波动、电流异常&#xff0c;还是设备故障&#xff0c;平台都能迅速捕捉并发出预警&#xff0c;确保电力供应的稳定和安全。 山海鲸可视化电力监控运维平台 想…

jpg压缩在线方法,我只用这2种(无损)

在数字化的时代&#xff0c;我们经常需要分享、存储或上传各种图像文件&#xff0c;而JPG是其中最常见的图像格式之一。然而&#xff0c;大文件大小有时可能成为一个问题&#xff0c;尤其是在网络传输或存储空间有限的情况下。为了解决这一问题&#xff0c;我们可以利用在线工具…

【嵌入式系统开发】002 VI编辑器入门

文章目录 0. 前言&#xff11;. VI编辑器简介1.1 什么是VI编辑器1.2 打开VI编辑器 2. VI编辑器的三种工作模式间&#xff08;模式切换与部分功能&#xff09;3. 移动操作4. 编辑4.1 插入4.2 删除 5. 复制、粘贴6. 查找、替换 0. 前言 对文件进行编辑时&#xff0c;如果是在有图…

gsoap2.8交叉编译方法(详细、亲测可用)

环境搭建 交叉编译器安装&#xff0c;过程略。 注意&#xff1a;如果要使用脚本配置环境变量&#xff0c;在运行脚本时&#xff0c;应该使用 . /绝对路径的方式&#xff0c;而不是直接/绝对路径或者./绝对路径&#xff0c;否则会导致配置失败。&#xff08;亲测如此&#xff0…

[巨详细]安装HBuilder-X教程

文章目录 下载HBuilder-X点击网址 &#xff0c;打开官网先点击所有产品&#xff0c;再点击HBuilder-X。进入HBuilder-X官网页面点击more&#xff0c;选择适合的版本下载。等待下载打开压缩包&#xff0c;点击HBuilderX.exe选择喜欢的风格关闭该弹窗&#xff0c;选择创建就创建成…

2024.06.05校招 实习 内推 面经

绿*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;内推/实习/校招汇总表格 1、实习 | 航天恒星2025届暑期实习生招聘启动 实习 | 航天恒星2025届暑期实习生招聘启动 2、实习 | 盛雄激光2025 “ 雏鹰计划 ” 实习生招募 实习 | 盛雄激光2025 “ 雏鹰计划 ” 实习生…