SpringBoot日常:整合属于自己的代码生成器

简介

代码生成器,顾名思义就是生成代码,我们经常做开发的公司一般都有属于自己的代码生成器,在开发需求的时候可以帮助我们快速生成代码,比如service文件、controller文件、mapper文件等等,甚至前端的也可以生成,但本章内容主要举例后端java内容。

生成器说明

本章内容主要采用mybatis-plus-generator 3.5.3.2新版本的生成器来生成代码,具体的细节可以访问官网查看mybatis-plus代码生成器

代码说明

本章的内容包含了配置、依赖、模板和生成代码的逻辑,可以拿来组成即用

properties配置

generator.properties

# 生成的目录
projectPath=D:/test
# ?模块名
moduleName=providers/test
# 包路径
packagePath=cn.baidu.sousuo.test
#
#XMLpackagePath=resources.mapper
# 作者
author=码至终章
# 多个表用英文逗号隔开
tables=user

# 数据库链接
database.url=jdbc:mysql://192.168.111.111:3306/test?serverTimezone=Asia/Shanghai
database.username=root
database.password=123454566776576

pom依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
            <version>2.6.3</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.25</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.12.0</version>
        </dependency>
    </dependencies>

生成器代码

CodeGenerator

public class CodeGenerator {

    /**
     * 代码生成入口
     * 注意: 请先修改resources目录下的generator.properties文件中的配置
     */
    public static void main(String[] args) {
        doFastGenerator();
        getPath();
    }

    private static Properties properties = new Properties();

    static {
        // 读取resources目录下的配置文件
        InputStream inputStream = CodeGenerator.class.getClassLoader().getResourceAsStream("generator.properties");
        try {
            properties.load(IoUtil.getReader(inputStream, Charset.defaultCharset()));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    // 数据库类型 MySQL
    private static final IDbQuery dbQuery = new MySqlQuery();

    private static void doFastGenerator() {

        String url = properties.getProperty("database.url");
        String username = properties.getProperty("database.username");
        String password = properties.getProperty("database.password");

        // 模块名称
        String moduleName = properties.getProperty("moduleName");
        // 项目目录
        String projectPath = properties.getProperty("projectPath");
//        String projectPath = System.getProperty("user.dir");
        // 作者名称
        String author = properties.getProperty("author");
        // 基础包路径
        String packagePath = properties.getProperty("packagePath");

        String xmlPackagePath = properties.getProperty("XMLpackagePath");
        // 需要生成的表
        String tables = properties.getProperty("tables");
        // 代码生成后是否打开磁盘目录
//        String openDir = properties.getProperty("openDir");

        // 1.数据库配置
        DataSourceConfig.Builder dataSourceConfigBuilder = new DataSourceConfig.Builder(url, username,
                password).dbQuery(dbQuery).typeConvert(new MySqlTypeConvert())
                .keyWordsHandler(new MySqlKeyWordsHandler());

        // 1.1.快速生成器
        FastAutoGenerator fastAutoGenerator = FastAutoGenerator.create(dataSourceConfigBuilder);

        // 2.全局配置
        fastAutoGenerator.globalConfig(globalConfigBuilder -> globalConfigBuilder.disableOpenDir()
                .outputDir(projectPath + "/" + moduleName + "/src/main/java")
                .author(author)
                .commentDate("yyyy-MM-dd HH:mm:ss")
                .dateType(DateType.TIME_PACK)
        );

        // 3.包配置
        fastAutoGenerator.packageConfig(packageConfigBuilder -> packageConfigBuilder.parent(packagePath)
                .moduleName(null)
                .entity("entity")
                .mapper("mapper")
                .xml("mapper")
                .service("service")
                .serviceImpl("service.impl")
                .controller("controller")
                .pathInfo(Collections.singletonMap(OutputFile.xml, projectPath + "/" + moduleName + "/src/main/resources/mapper")));

        // 4.模板配置
        AbstractTemplateEngine templateEngine = new FreemarkerTemplateEngine();
        fastAutoGenerator.templateEngine(templateEngine);

        // 5.注入配置 T
        Map<String, Object> customMap = new HashMap<>();
        customMap.put("dtoPackage", packagePath);
        customMap.put("voPackage", packagePath);
        Map<String, String> customFile = new HashMap<>();
        customFile.put("DTO.java", "/templates/DTO.ftl");
        customFile.put("VO.java", "/templates/VO.ftl");
        customFile.put("PageDTO.java", "/templates/PageDTO.ftl");
        fastAutoGenerator.injectionConfig(injectionConfigBuilder -> injectionConfigBuilder.customMap(customMap).customFile(customFile));

        // 6.策略配置
        fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.enableCapitalMode()
                .enableSkipView()
                .disableSqlFilter()
                .addInclude(tables)
                .addTablePrefix(""));

        // 6.1.Entity策略配置  如果不需要生成注解,去掉.enableTableFieldAnnotation()
        fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.entityBuilder()
                .enableFileOverride()
                .enableTableFieldAnnotation()
                .enableLombok()
                .enableChainModel()
                .enableTableFieldAnnotation()
                // 如果要生效,需要设置主键不自增
                .idType(IdType.ASSIGN_ID)
                .naming(NamingStrategy.underline_to_camel)
                .columnNaming(NamingStrategy.underline_to_camel));

        // 6.2.Controller策略配置
        // 开启生成@RestController控制器
        fastAutoGenerator
                .strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.controllerBuilder()
                        .enableFileOverride()
                        .enableRestStyle());

        // 6.3.Service策略配置
        fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.serviceBuilder()
                .enableFileOverride()
                .formatServiceFileName("%sService")
                .formatServiceImplFileName("%sServiceImpl"));

        // 6.4.Mapper策略配置
        fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.mapperBuilder()
                .enableFileOverride()
                .formatMapperFileName("%sMapper")
                .formatXmlFileName("%sMapper"));

        // 6.5.配置模板
        String absolutePath = File.separator + "templates";
        String mapperTempPath = absolutePath + File.separator + "MapperP";
        String entityTempPath = absolutePath + File.separator + "EntityP";
        String controllerTempPath = absolutePath + File.separator + "ControllerP";
        String serviceTempPath = absolutePath + File.separator + "ServiceP";
        String serviceImplTempPath = absolutePath + File.separator + "ServiceImplP";
        String mapperxmlTempPath = absolutePath + File.separator + "MapperXml";
        fastAutoGenerator.templateConfig(strategyConfigBuilder -> strategyConfigBuilder
                .mapper(mapperTempPath)
                .service(serviceTempPath)
                .serviceImpl(serviceImplTempPath)
                .entity(entityTempPath)
                .xml(mapperxmlTempPath)
                .controller(controllerTempPath)
                .build());
        // 7.生成代码
        fastAutoGenerator .templateEngine(new FreemarkerTemplateEngine()).execute();

    }

    /**
     * 获取当前项目本地磁盘目录
     */
    private static void getPath() {
        System.out.println("当前项目本地磁盘目录->" + System.getProperty("user.dir"));
    }
}

模板文件

controllerP.ftl
package ${package.Controller};

import ${dtoPackage}.${entity}DTO;
import ${dtoPackage}.${entity}PageDTO;
import ${voPackage}.${entity}VO;
import ${package.Service}.${entity}Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import com.github.pagehelper.PageInfo;
import java.util.Set;
import java.util.List;

/**
* @Description ${table.comment!} 控制器
* @author ${author}
* @date ${date}
*/

/**
* 总请求控制器
*
* @return 形式返回
*/
@RestController
@RequestMapping(value = "/${table.name}")
public class ${table.controllerName} {

    @Autowired
    private ${entity}Service  ${table.entityPath}Service;

    /**
    * 分页查询
    *
    * @param request
    * @return
    */
    @PostMapping(value = "/page")
    public Result<PageInfo> page(@RequestBody PageDTO params) {
        return Result.ok(${table.entityPath}Service.page(params));
    }

    /**
    * 列表查询
    *
    * @param request
    * @return
    */
    @PostMapping(value = "/list")
    public Result<List<${entity}VO>> list(@RequestBody ${entity}DTO params){
        return Result.ok(${table.entityPath}Service.list(params));
    }

    /**
    * 创建
    *
    * @param request
    * @return
    */
    @PostMapping("/create")
    public Result<Boolean> create(@RequestBody ${entity}DTO params){
        return Result.ok(${table.entityPath}Service.create(params));
    }

    /**
    * 修改
    *
    * @param request
    * @return
    */
    @PostMapping(value = "/update")
    public Result<Boolean> update(@RequestBody ${entity}DTO params){
        return Result.ok(${table.entityPath}Service.update(params));
    }

    /**
    * 查询详情
    *
    * @param id
    * @return
    */
    @GetMapping("/details")
    public Result<${entity}VO> details(@RequestParam Long id){
        return Result.ok(${table.entityPath}Service.details(id));
    }

    /**
    * 删除
    *
    * @param ids
    * @return
    */
    @PostMapping(value = "/deleteByIds")
    public Result<Boolean> deleteByIds(@RequestParam Set<String> ids){
        return Result.ok(${table.entityPath}Service.deleteByIds(ids));
    }
}
DTO.ftl
package ${dtoPackage};


import lombok.*;
import java.time.LocalDateTime;
import java.util.Date;
import java.io.Serializable;

/**
* @author ${author}
* @Description ${table.comment!} 数据传输对象
* @date ${date}
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ${entity}DTO implements Serializable {
<#list table.fields as field>
    <#if field.comment != "" >
    /**
    * ${field.comment}
    */
    </#if>
    private ${field.propertyType} ${field.propertyName};

</#list>
}
Entity.ftl
package ${package.Entity};

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

<#assign a = 0>
<#assign b = 0>
<#assign c = 0>
<#list table.fields as field>
    <#if field.propertyType = "LocalDateTime" && a = 0>
        import java.time.LocalDateTime;
        <#assign a = a + 1>
    </#if>
    <#if field.propertyType = "LocalDate" && b = 0>
        import java.time.LocalDate;
        <#assign b = b + 1>
    </#if>
    <#if field.propertyType = "BigDecimal" && c = 0>
        import java.math.BigDecimal;
        <#assign c = c + 1>
    </#if>
</#list>

/**
* ${table.comment!}
*
* @author ${author}
* @date ${date}
*/
@Data
@TableName("${table.name}")
public class ${entity} {

<#-- ----------  BEGIN 字段循环遍历  ---------->
<#list table.fields as field>
    /**
    * ${field.comment}
    */
    <#if field.keyFlag>
        <#assign keyPropertyName="${field.propertyName}"/>
    </#if>
    <#if field.keyFlag>
    <#-- 主键 -->
        <#if field.keyIdentityFlag>
    @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
        <#elseif idType??>
    @TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
        <#else>
    @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>
    <#else>
    @TableField("${field.annotationColumnName}")
    </#if>
<#-- 乐观锁注解 -->
    <#if (versionFieldName!"") == field.name>
        @Version
    </#if>
<#-- 逻辑删除注解 -->
    <#if (logicDeleteFieldName!"") == field.name>
        @TableLogic
    </#if>
    private ${field.propertyType} ${field.propertyName};
</#list>
<#------------  END 字段循环遍历  ---------->
}

MapperP.ftl
package ${package.Mapper};

import ${package.Entity}.${entity};
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

/**
* ${table.comment!}${table.name}表持久层接口
*
* @author ${author}
* @since ${date}
*/
@Mapper
public interface ${table.mapperName} extends BaseMapper<${entity}> {

}

MapperXml.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}.${table.mapperName}">

<#if enableCache>
    <!-- 开启二级缓存 -->
    <cache type="${cacheClassName}"/>

</#if>
<#if baseResultMap>
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="${package.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>
</mapper>

PageDTO.ftl
package ${dtoPackage};


import lombok.*;
import java.time.LocalDateTime;
import java.util.Date;
import java.io.Serializable;

/**
* @author ${author}
* @Description ${table.comment!} 数据传输对象
* @date ${date}
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class ${entity}PageDTO extends BaseDTO implements Serializable {
<#list table.fields as field>
    <#if field.comment != "" >
    /**
    * ${field.comment}
    */
    </#if>
    private ${field.propertyType} ${field.propertyName};

</#list>
}
ServiceImplP.ftl
package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${entity}Service;
import ${dtoPackage}.${entity}DTO;
import ${dtoPackage}.${entity}PageDTO;
import ${voPackage}.${entity}VO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import com.github.pagehelper.PageInfo;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import java.util.Set;
import java.util.List;

/**
* @author ${author}
* @since ${date}
*/
@Slf4j
@Service
public class ${entity}ServiceImpl extends ServiceImpl<${table.mapperName}, ${entity}> implements ${entity}Service {

    @Autowired
    private ${table.mapperName} ${table.entityPath}Mapper;


    @Override
    public PageInfo<${entity}VO> page(${entity}PageDTO pageDto) {
        PageHelper.startPage(pageDto.getPageNum(), pageDto.getPageSize());
        LambdaQueryWrapper<${entity}> queryWrapper = Wrappers.lambdaQuery(${entity}.class);
        List<${entity}> list = this.list(queryWrapper);
        PageInfo pageInfo = new PageInfo<>(list);
        List<${entity}VO> convertPageList = Convert.convert(new TypeReference<List<${entity}VO>>() {}, pageInfo.getList());
        pageInfo.setList(convertPageList);
        return pageInfo;
    }


    @Override
    public List<${entity}VO> list(${entity}DTO queryDto) {
        LambdaQueryWrapper<${entity}> queryWrapper = Wrappers.lambdaQuery(HrEmailConfigT.class);
        List<${entity}> list = this.list(queryWrapper);
        return Convert.convert(new TypeReference<List<${entity}VO>>() {}, list);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean create(${entity}DTO createDto) {
        HrEmailConfigT convert = Convert.convert(${entity}.class, createDto);
        hrEmailConfigTMapper.insert(convert);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean update(${entity}DTO updateDto) {
        HrEmailConfigT convert = Convert.convert(${entity}.class, updateDto);
        hrEmailConfigTMapper.updateById(convert);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean deleteByIds(Set<String> ids) {
        hrEmailConfigTMapper.deleteBatchIds(ids);
        return true;
    }

    @Override
    public ${entity}VO details(Long id) {
        HrEmailConfigT hrEmailConfigT = hrEmailConfigTMapper.selectById(id);
        return Convert.convert(${entity}VO.class, hrEmailConfigT);
    }


}

ServiceP.ftl
package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${entity}Service;
import ${dtoPackage}.${entity}DTO;
import ${dtoPackage}.${entity}PageDTO;
import ${voPackage}.${entity}VO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import com.github.pagehelper.PageInfo;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import java.util.Set;
import java.util.List;

/**
* @author ${author}
* @since ${date}
*/
@Slf4j
@Service
public class ${entity}ServiceImpl extends ServiceImpl<${table.mapperName}, ${entity}> implements ${entity}Service {

    @Autowired
    private ${table.mapperName} ${table.entityPath}Mapper;


    @Override
    public PageInfo<${entity}VO> page(${entity}PageDTO pageDto) {
        PageHelper.startPage(pageDto.getPageNum(), pageDto.getPageSize());
        LambdaQueryWrapper<${entity}> queryWrapper = Wrappers.lambdaQuery(${entity}.class);
        List<${entity}> list = this.list(queryWrapper);
        PageInfo pageInfo = new PageInfo<>(list);
        List<${entity}VO> convertPageList = Convert.convert(new TypeReference<List<${entity}VO>>() {}, pageInfo.getList());
        pageInfo.setList(convertPageList);
        return pageInfo;
    }


    @Override
    public List<${entity}VO> list(${entity}DTO queryDto) {
        LambdaQueryWrapper<${entity}> queryWrapper = Wrappers.lambdaQuery(HrEmailConfigT.class);
        List<${entity}> list = this.list(queryWrapper);
        return Convert.convert(new TypeReference<List<${entity}VO>>() {}, list);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean create(${entity}DTO createDto) {
        HrEmailConfigT convert = Convert.convert(${entity}.class, createDto);
        hrEmailConfigTMapper.insert(convert);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean update(${entity}DTO updateDto) {
        HrEmailConfigT convert = Convert.convert(${entity}.class, updateDto);
        hrEmailConfigTMapper.updateById(convert);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean deleteByIds(Set<String> ids) {
        hrEmailConfigTMapper.deleteBatchIds(ids);
        return true;
    }

    @Override
    public ${entity}VO details(Long id) {
        HrEmailConfigT hrEmailConfigT = hrEmailConfigTMapper.selectById(id);
        return Convert.convert(${entity}VO.class, hrEmailConfigT);
    }


}

VO.ftl
package ${voPackage};

import lombok.Data;
import java.io.Serializable;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.Date;

/**
* @author ${author}
* @Description ${table.comment!} 数据返回对象
* @date ${date}
*/
@Data
public class ${entity}VO implements Serializable {
<#list table.fields as field>
    <#if field.comment != "" >
    /**
    * ${field.comment}
    */
    </#if>
    private ${field.propertyType} ${field.propertyName};

</#list>
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值