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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DVWA 靶场 SQL Injection (Blind) 通关解析

前言 DVWA代表Damn Vulnerable Web Application&#xff0c;是一个用于学习和练习Web应用程序漏洞的开源漏洞应用程序。它被设计成一个易于安装和配置的漏洞应用程序&#xff0c;旨在帮助安全专业人员和爱好者了解和熟悉不同类型的Web应用程序漏洞。 DVWA提供了一系列的漏洞场…

微型操作系统内核源码详解系列五(五):cm3下Pendsv切换任务上篇

系列一&#xff1a;微型操作系统内核源码详解系列一&#xff1a;rtos内核源码概论篇&#xff08;以freertos为例&#xff09;-CSDN博客 系列二&#xff1a;微型操作系统内核源码详解系列二&#xff1a;数据结构和对象篇&#xff08;以freertos为例&#xff09;-CSDN博客 系列…

C++初学者指南第一步---8.类型系统(基础)

C初学者指南第一步—8.类型系统&#xff08;基础&#xff09; 文章目录 C初学者指南第一步---8.类型系统&#xff08;基础&#xff09;1.用const声明常量2.类型别名3.类型推导 auto4.常量表达式&#xff1a;constexpr (C11) 1.用const声明常量 语法&#xff1a; Type const v…

君子小人的格局、境界

子曰&#xff1a;君子怀德&#xff0c;小人怀土&#xff1b;君子怀刑&#xff0c;小人怀惠。 直译&#xff1a;君子怀念道德&#xff0c;小人怀念乡土&#xff1b;君子关心法度&#xff0c;小人关心恩惠。 这里的君子与小人只是体现格局、境界的不同&#xff1b; 君子怀的是德…

Windows环境利用 OpenCV 中 CascadeClassifier 分类器识别人眼 c++

Windows环境中配置OpenCV 关于在Windows环境中配置opencv的说明&#xff0c;具体可以参考&#xff1a;VS2022 配置OpenCV开发环境详细教程。 CascadeClassifier 分类器 CascadeClassifier 是 OpenCV 库中的一个类&#xff0c;它用于实现一种快速的物体检测算法&#xff0c;称…

一些3D数据集的简单介绍

一、Objaverse 1.0 Objaverse 1.0: a large dataset of objects with 800K (and growing) 3D models with descriptive captions, tags and animations. Assets not only belong to varied categories like animals, humans, and vehicles, but also include interiors and ex…

【课程总结】Day10:卷积网络的基本组件

前言 由于接下来的课程内容将围绕计算机视觉展开&#xff0c;其中接触最多的内容是卷积、卷积神经网络等…因此&#xff0c;本篇内容将从卷积入手&#xff0c;梳理理解&#xff1a;卷积的意义、卷积在图像处理中的作用以及卷积神经网络的概念&#xff0c;最后利用pytorch搭建一…

Vue76-路由对浏览器历史记录的影响

一、push模式 默认是push 二、replace模式 替换当前记录&#xff01; &#xff08;当前指针指向的那一条记录&#xff09; 三、小结

只有一个鸿蒙好?还是鸿蒙、安卓、IOS并存好?

这个话题&#xff0c;现在很敏感&#xff0c;为了防止被喷&#xff0c;我提前且清楚的交待我的观点&#xff1a;我双手欢迎鸿蒙、欢迎仓颉&#xff0c;而且我已经用行动来支持&#xff0c;比如2021年刚发布ArkUI时&#xff0c;我就第一时间上手了&#xff0c;且这几年一直在跟进…

图解Transformer

图解Transformer Transformer模型是在论文《Attention is All You Need》中提出的。它的TensorFlow实现作为Tensor2Tensor包的一部分是可用的。哈佛大学的自然语言处理小组创建了一个指南&#xff0c;用PyTorch实现对论文进行了注释。在这篇文章中&#xff0c;我们将尝试简化一…

【IEEE独立出版、有确定的ISBN号】第三届能源与电力系统国际学术会议 (ICEEPS 2024)

第三届能源与电力系统国际学术会议 (ICEEPS 2024) 2024 3rd International Conference on Energy and Electrical Power Systems 连续2届会后4-5个月EI检索&#xff0c;检索稳定&#xff01; 成功申请IEEE出版&#xff01; 特邀院士、Fellow 报告&#xff01; 一、大会信息 …

如何恢复丢失的文件?免费为 Mac 恢复数据

丢失 Mac 上的重要文件是一件非常痛苦的事情。无论是重要的工作文件、重要文件还是心爱的照片&#xff0c;意外删除它们或出现系统错误都会非常令人沮丧。别担心&#xff1b;有办法&#xff1a;奇客数据恢复Mac版。这款免费的 Mac 文件恢复软件就像您文件的救星 - 当出现问题时…

【密码学】分组密码

文章目录 分组密码的模式分组密码与流密码模式明文分组与密文分组 ECB模式ECB定义ECB特点对ECB模式的攻击改变分组顺序攻击 CBC模式CBC定义初始化向量IVCBC特点对CBC模式的攻击对初始向量进行反转攻击填充提示攻击 CFB模式CFB定义对CFB模式的攻击重放攻击 OFB模式OFB定义CFB模式…

深入学习-Gradle-自动化构建技术(二)Groovy-筑基

但是&#xff0c;如果你这个类或变量要用于其它模块的&#xff0c;建议不要使用 def&#xff0c;还是应该使用 Java 中的那种强类型定义方式&#xff0c;因为使用强类型的定义方式&#xff0c;它不能动态转换为其它类型&#xff0c;它能够保证外界传递进来的值一定是正确的。如…

程序猿大战Python——面向对象——私有权限

私有属性 目标&#xff1a;掌握私有属性的使用。 为了更好的限制属性的访问和包含隐私&#xff0c;可以给属性设置私有权限。 当把属性设置为私有属性后&#xff0c;则该属性只能被本类直接访问。 定义私有属性语法&#xff1a; self.__属性名 设置和获取私有属性值语法&am…

Interleaving Retrieval with Chain-of-Thought Reasoning for ... 论文阅读

Interleaving Retrieval with Chain-of-Thought Reasoning for Knowledge-Intensive Multi-Step Questions 论文阅读 文章目录 Interleaving Retrieval with Chain-of-Thought Reasoning for Knowledge-Intensive Multi-Step Questions 论文阅读 Abstract介绍相关工作开放域QA提…

【物联网】NB-IoT

目录 一、什么是NBIOT 二、NB-IoT的特点 三、NBIOT的工作状态 四、移远NB-IoT模块及AT指令 一、什么是NBIOT NB-IoT&#xff08;Narrow Band Internet of Things&#xff09;窄带物联网&#xff0c;构建于蜂窝网络&#xff0c;所占用的带宽很窄&#xff0c;只需约180KHz&am…

易基因:【表观遗传学基础】如何研究DNA甲基化

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 表观遗传学近几年取得的一系列研究进展&#xff0c;确实吸引着越来越多的关注&#xff01;为了帮大伙儿梳理一下表观遗传学的基本概念和研究方法&#xff0c;小编打算开一个系列专题&…

工业数字孪生:智能制造的新引擎

数字孪生技术&#xff1a;智能制造的新引擎 一、数字孪生技术的基本概念与工业应用 1.1 数字孪生的定义与原理 数字孪生技术是一种先进的集成技术&#xff0c;它通过在数字空间创建一个精准物理对象的虚拟模型&#xff0c;使得我们可以在数字空间中模拟、分析和预测物理实体…