MyBatis Plus Generator代码生成

news2025/1/14 11:51:48

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

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

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

相关文章

怎么控制多个存储设备的访问权限?数据安全存储方案来了

数据安全存储是指将数据以安全的方式存储在存储系统中&#xff0c;以确保数据的机密性、完整性和可用性。要控制数据安全存储的权限以保障安全&#xff0c;可以采取以下措施&#xff1a; 访问控制列表&#xff08;ACLs&#xff09;&#xff1a;使用ACLs来定义对存储数据的访问权…

丹麦海外媒体报道:媒体投放发稿助力企业在海外扭转战局

大舍传媒 丹麦海外媒体报道中&#xff0c;大舍传媒作为一家专业的媒体投放公司&#xff0c;正发挥着重要作用&#xff0c;帮助企业在海外扭转战局。作为丹麦领先的媒体投放机构&#xff0c;他们为企业提供了全方位的品牌传播服务&#xff0c;帮助企业在海外市场取得成功。 大舍…

MySQL 架构

本篇主要介绍一下MySQL的架构 目录 一、整体架构 二、连接层 网络端口 连接管理线程 三、服务层 NoSQL接口与SQL接口 Parser&#xff08;语法分析器&#xff09; Optimizer&#xff08;查询优化器&#xff09; Cache & Buffers(缓存&#xff09; 四、存储引擎层…

可复用验证的测试用例 5大编写技巧

编写可复用验证的测试用例&#xff0c;节省了编写新测试用例的时间和资源&#xff0c;提高了测试效率和项目质量&#xff0c;减少错误修复成本&#xff0c;有利于实现较高的投入产出比。缺乏可复用的测试用例会导致测试团队不断重复创建相似的测试场景&#xff0c;消耗大量时间…

CleanMyMac中文版2024破解版安装包下载最新官方免费激活码

CleanMyMac中文版&#xff0c;让你的电脑焕然一新&#xff01; 大家好&#xff0c;今天我要给大家推荐一款神奇的软件——CleanMyMac中文版。作为一个长期使用Mac的用户&#xff0c;我一直在寻找一款能够彻底清理电脑垃圾和优化系统的工具&#xff0c;而CleanMyMac正是我心心念…

封装音视频编解码和渲染的动态链接库编译和测试

1.动态链接库的编译 生成了以下几个文件 我们把生成的lib文件复制到lib文件夹中 其余三个文件不变动 2.进行测试看是否可以用生成的xcodec.lib库文件里的接口函数 以上是重新创建的新项目&#xff0c;导入了xcodec.lib&#xff0c;其他配置同以前项目 库测试结果 运行显示我们…

优思学院|精益生产10大工具全解析

精益生产是一种管理哲学&#xff0c;其核心思想是通过消除浪费、持续改进和最大化价值来提高企业效率和效益。本文将详细解析精益生产的10大工具&#xff0c;帮助企业更好地理解和实施精益生产&#xff0c;以实现卓越的经营绩效。 一、价值流图 (Value Stream Mapping) 前言 …

大模型的分类:探索多样化的人工智能模型

随着人工智能技术的飞速发展&#xff0c;大型预训练模型&#xff08;以下简称“大模型”&#xff09;已经在自然语言处理、计算机视觉、语音识别等多个领域取得了显著的成果。这些模型通过在海量数据上进行预训练&#xff0c;能够捕捉到丰富的特征信息&#xff0c;为各种下游任…

C#标志位的使用

C#作为一种功能强大的编程语言&#xff0c;是在.NET框架中广泛使用的语言之一。在实际应用中&#xff0c;C#的标志位在各种系统设计和编程实践中会涉及到。这篇文章将讨论如何使用C#的标志位来跟踪报警声音的播放状态。 报警系统是一种广泛应用的系统&#xff0c;它可以在关键时…

软件性能测试之负载测试、压力测试详情介绍

负载测试和压力测试是软件性能测试中的两个重要概念&#xff0c;它们在保证软件质量和性能方面起到至关重要的作用&#xff0c;本文将从多个角度详细介绍这两种测试类型。 一、软件负载测试   负载测试是在特定条件下对软件系统进行长时间运行和大数据量处理的测试&#xff…

shell脚本中的变量

关于Linux操作系统中当前shell进程与子shell进程的详细解释 如上图所示&#xff0c;使用ps -f可以当前查看Linux操作系统中当前正在运行的进程。 然后敲bash后&#xff0c;相当于在当前的bash shell环境下又创建了一个子bash shell的进程&#xff0c; 如上图所示&#xff0c;…

Apache Druid-时序数据库

Apache Druid&#xff1a;是是一个集时间序列数据库、数据仓库和全文检索系统特点于一体的分析性数据平台&#xff0c;旨在对大型数据集进行快速的查询分析&#xff08;"OLAP"查询)。Druid最常被当做数据库来用以支持实时摄取、高性能查询和高稳定运行的应用场景&…

手把手带你实现一个简单的轮播图

轮播图现有成熟的插件非常多&#xff0c;但做为一名学习中的想要成为前端开发的小伙伴们来说&#xff0c;自己动手实现一个轮播图&#xff0c;还是很锻炼的&#xff0c;实现完成后&#xff0c;也是很有成就感的。下面&#xff0c;我们来实现一个简单的轮播图吧。 目录 1 HTML …

DIY一个PE启动盘

原文&#xff1a;https://blog.c12th.cn/archives/18.html 前言 有天&#xff0c;朋友问我有没有带集成软件的U盘启动盘。我也是很久没有弄启动盘了&#xff0c;有次在逛b站时无意中看到还有可以DIY的启动盘&#xff0c;于是就教程就来了… 该两种方法&#xff0c;已在三台实体…

SCADA软件地毯式介绍,你想知道的都在这里.

很多小伙伴对SCADA很陌生&#xff0c;殊不知这个可是智慧工业制造的大脑和中枢神经&#xff0c;很多指令的发出&#xff0c;监控状态的现实都得通过这个系统&#xff0c;本文详解介绍一下什么是SCADA&#xff0c;重大作用&#xff0c;其在工业制造中的位置&#xff0c;以及市面…

停车场控制机系统哪家好?捷顺捷曜分体式车场控制机有哪些功能亮点?

停车场控制机为现代城市提供了许多便利和好处。首先&#xff0c;它能够自动记录车辆进出的时间&#xff0c;便于车主和管理人员进行费用计算。其次&#xff0c;通过车牌识别技术&#xff0c;提高了车辆进出的效率&#xff0c;减少了排队等待时间。此外&#xff0c;控制机还可以…

【Pepper机器人开发与应用】二、Pepper机器人图形化开发:医疗服务机器人程序设计

‍‍&#x1f3e1;博客主页&#xff1a; virobotics(仪酷智能)&#xff1a;LabVIEW深度学习、人工智能博主 &#x1f4d1;上期文章&#xff1a;『【Pepper机器人开发与应用】一、教你如何使用图形化开发软件高效开发pepper机器人&#xff08;Pepper SDK for LabVIEW&#xff09…

MFC开发 解决:VSstudio2019 无法打开afxwin.h 或 安装afxwin.h

在进行MFC开发的学习中&#xff0c;在win10系统下使用vs studio2019进行mfc开发&#xff0c;出现的标题的问题 首先&#xff0c;如果你以及安装过了afxwin.h相关环境 那么按照如下步骤 首先 打开工程的属性 在 高级——MFC的使用——选择在共享DLL中使用MFC 如下 …

JVM 基本组成

一、为什么要学习 JVM &#xff1f; 1. “ ⾯试造⽕箭&#xff0c;⼯作拧螺丝” &#xff0c; JVM 属于⾯试官特别喜欢提问的知识点&#xff1b; 2. 未来在⼯作场景中&#xff0c;也许你会遇到以下场景&#xff1a; 线上系统突然宕机&#xff0c;系统⽆法访问&#xff0c;甚⾄直…

【AICFD教程】汽车外气动仿真,小白学CFD的入门案例

【视频教程】 【教程】汽车外气动仿真&#xff0c;小白学CFD的入门案例 【文字教程】 1. 案例背景 1.1 学习目标 本案例针对某汽车仿真模型&#xff0c;在车速为40m/s时进行了汽车外流场的数值模拟。 本案例教程旨在演示AICFD中以下场景与功能的操作&#xff1a; a. 单域外…