CrudBoy快乐水-编写代码生成器

简介: CrudBoy快乐水-编写代码生成器

没有理由不根据自己的项目编写一套适合自己项目的代码生成工具,不是吗?


思路: 首先根据自己的项目情况,定义好代码模板与占位参数,生成的时候只需要将参数填进去,再在指定的位置生成相应的.java/.xml等文件即可

使用freemarker模板引擎    compile 'org.freemarker:freemarker:2.3.23'


# 核心源源码

package com.futao.springbootdemo.utils.generator;
import com.futao.springbootdemo.foundation.ApplicationException;
import com.futao.springbootdemo.utils.DateTools;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
 * 代码生成器
 *
 * @author futao
 * Created on 2019-03-08.
 */
public class CodeGeneratorManager {
    private static final Logger LOGGER = LoggerFactory.getLogger(CodeGeneratorManager.class);
    /**
     * 项目基础路径
     */
    private static final String PROJECT_BASE_PATH = System.getProperty("user.dir") + "/src/main/java/com/futao/springbootdemo";
    /**
     * 模板文件路径
     */
    private static final String TEMPLATE_FILE_PATH = PROJECT_BASE_PATH + "/utils/generator/template";
    /**
     * Entity生成路径
     */
    private static final String ENTITY_PATH = PROJECT_BASE_PATH + "/model/entity";
    /**
     * Controller路径
     */
    private static final String CONTROLLER_PATH = PROJECT_BASE_PATH + "/controller/business";
    /**
     * Service实现类生成路径
     */
    private static final String SERVICE_IMPL_PATH = PROJECT_BASE_PATH + "/service/impl";
    /**
     * Service接口生成路径
     */
    private static final String SERVICE_FACE_PATH = PROJECT_BASE_PATH + "/service";
    /**
     * Dao Mapper路径
     */
    private static final String DAO_PATH = PROJECT_BASE_PATH + "/dao";
    /**
     * Mybatis mapper xml文件路径
     */
    private static final String MYBATIS_MAPPER_XML_PATH = System.getProperty("user.dir") + "/src/main/resources/mybatis/mapper";
    private static Configuration configuration = null;
    private CodeGeneratorManager() {
    }
    /**
     * Freemarker 模板环境配置
     *
     * @return
     * @throws IOException
     */
    private Configuration initFreemarkerConfiguration() {
        Configuration cfg;
        try {
            cfg = new Configuration(Configuration.VERSION_2_3_23);
            cfg.setDirectoryForTemplateLoading(new File(TEMPLATE_FILE_PATH));
            cfg.setDefaultEncoding("UTF-8");
            cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
        } catch (IOException e) {
            throw new RuntimeException("Freemarker 模板环境初始化异常!", e);
        }
        return cfg;
    }
    /**
     * 获取模板文件
     *
     * @return
     */
    private Template getTemplate(String templateName) {
        if (configuration == null) {
            configuration = initFreemarkerConfiguration();
        }
        try {
            return configuration.getTemplate(templateName);
        } catch (IOException e) {
            e.printStackTrace();
            throw ApplicationException.ae(e.getMessage());
        }
    }
    /**
     * 生成代码
     *
     * @param args
     */
    public static void main(String[] args) {
        CodeGeneratorManager codeGeneratorManager = new CodeGeneratorManager();
        Map<String, Object> dataMap = new HashMap<>(6);
        dataMap.put("className", "Address");
        dataMap.put("classDesc", "地址");
        dataMap.put("createDate", DateTools.dateToString(new Date(), DateTools.yyyyMMdd));
        dataMap.put("controllerPackagePath", getPackagePath(CONTROLLER_PATH));
        dataMap.put("entityPackagePath", getPackagePath(ENTITY_PATH));
        dataMap.put("serviceFacePackagePath", getPackagePath(SERVICE_FACE_PATH));
        dataMap.put("serviceImplPackagePath", getPackagePath(SERVICE_IMPL_PATH));
        dataMap.put("daoPackagePath", getPackagePath(DAO_PATH));
        Template entityTemplate = codeGeneratorManager.getTemplate("EntityTemplate.ftl");
        Template controllerTemplate = codeGeneratorManager.getTemplate("ControllerTemplate.ftl");
        Template serviceFaceTemplate = codeGeneratorManager.getTemplate("ServiceFaceTemplate.ftl");
        Template serviceImplTemplate = codeGeneratorManager.getTemplate("ServiceImplTemplate.ftl");
        Template daoTemplate = codeGeneratorManager.getTemplate("DaoTemplate.ftl");
        Template mapperTemplate = codeGeneratorManager.getTemplate("MapperTemplate.ftl");
        File entityFile = new File(ENTITY_PATH + "/" + dataMap.get("className") + ".java");
        File controllerFile = new File(CONTROLLER_PATH + "/" + dataMap.get("className") + "Controller.java");
        File serviceFaceFile = new File(SERVICE_FACE_PATH + "/" + dataMap.get("className") + "Service.java");
        File serviceImplFile = new File(SERVICE_IMPL_PATH + "/" + dataMap.get("className") + "ServiceImpl.java");
        File daoFile = new File(DAO_PATH + "/" + dataMap.get("className") + "Dao.java");
        File mapperFile = new File(MYBATIS_MAPPER_XML_PATH + "/" + dataMap.get("className") + "Mapper.xml");
        try {
            entityTemplate.process(dataMap, new FileWriter(entityFile));
            System.out.println(">>>> 实体类【" + dataMap.get("className") + "】生成成功");
            controllerTemplate.process(dataMap, new FileWriter(controllerFile));
            System.out.println(">>>> 控制器类【" + dataMap.get("className") + "Controller】生成成功");
            serviceFaceTemplate.process(dataMap, new FileWriter(serviceFaceFile));
            System.out.println(">>>> Service接口【" + dataMap.get("className") + "Service】生成成功");
            serviceImplTemplate.process(dataMap, new FileWriter(serviceImplFile));
            System.out.println(">>>> Service实现类【" + dataMap.get("className") + "ServiceImpl】生成成功");
            daoTemplate.process(dataMap, new FileWriter(daoFile));
            System.out.println(">>>> Dao接口【" + dataMap.get("className") + "Dao】生成成功");
            mapperTemplate.process(dataMap, new FileWriter(mapperFile));
            System.out.println(">>>> Mapper文件【" + dataMap.get("className") + "Mapper】生成成功");
            System.out.println(StringUtils.repeat("=", 20) + "执行完毕" + StringUtils.repeat("=", 20));
        } catch (TemplateException | IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 根据文件系统路径获取包路径
     *
     * @param fileSysPath 文件系统路径
     * @return
     */
    private static String getPackagePath(String fileSysPath) {
        return fileSysPath.substring(fileSysPath.indexOf("com")).replace("/", ".");
    }
}

# 代码模板(只贴出两个示例)


  • Controller.java

package ${controllerPackagePath};
import ${entityPackagePath}.${className};
import ${serviceFacePackagePath}.${className}Service;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* ${classDesc}操作接口
*
* @author futao
* Created on ${createDate}.
*/
@Api("${classDesc}")
@RestController
@RequestMapping(path = "${className?lower_case}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class ${className}Controller {
    @Resource
    private ${className}Service ${className?lower_case}Service;
    /**
    * 新增${classDesc}
    *
    * @return
    */
    @ApiOperation("新增${classDesc}")
    @PostMapping(path = "add")
    public ${className} add(
    ) {
    return ${className?lower_case}Service.add();
    }
    /**
    * 删除${classDesc}
    *
    * @param id 要删除的${classDesc}的id
    * @return
    */
    @DeleteMapping("{id}")
    public ${className} delete(
        @PathVariable("id") String id
    ) {
    return ${className?lower_case}Service.delete(id);
    }
    /**
    * 更新${classDesc}
    *
    * @param id 要更新的${classDesc}的id
    * @return
    */
    @PutMapping("{id}")
    public ${className} update(
        @PathVariable("id") String id
    ) {
        return ${className?lower_case}Service.update(id);
    }
    /**
    * 查询${classDesc}列表
    *
    * @return
    */
    @GetMapping("list")
    public List<${className}> list() {
        return ${className?lower_case}Service.list();
    }
    /**
    * 获取${classDesc}详情
    *
    * @param id ${classDesc}id
    * @return
    */
    @GetMapping("{id}")
    public ${className} byId(@PathVariable("id") String id) {
        return ${className?lower_case}Service.byId(id);
    }
}
  • Mapper.xml

<?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="${daoPackagePath}.${className}Dao">
    <!--配置一个LRU缓存(二级缓存),每隔60秒进行刷新,存储512个对象-->
    <!--
        LRU     最近最少使用策略,移除最长时间不被使用的对象
        FIFO    先进先出策略
        SOFT    软引用策略,移除基于垃圾回收器状态和软引用规则的对象
        WEAK    弱引用策略,更积极地移除基于垃圾回收器状态和软引用规则的对象
    -->
    <cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
    <insert id="add" parameterType="${className?lower_case}">
        insert
        into springmvcdemo.futao_${className?lower_case} ()
        values ();
    </insert>
    <delete id="delete" parameterType="string">
        delete
        from springmvcdemo.futao_${className?lower_case}
        where id = ${r"#{id}"}
    </delete>
    <update id="update" parameterType="${className?lower_case}">
        update springmvcdemo.futao_${className?lower_case}
        set
        where id = ${r"#{id}"}
    </update>
    <select id="list">
        select *
        from springmvcdemo.futao_${className?lower_case}
    </select>
    <select id="byId" parameterType="string">
        select *
        from springmvcdemo.futao_${className?lower_case}
        where id = ${r"#{id}"}
    </select>
</mapper>


根据自己的项目情况创建模板即可,比如我就创建了6个


image.png

# 使用


直接执行 CodeGeneratorManager#main 方法即可


image.png


效果


image.png

image.png

image.png


无解~

快乐~

源代码: https://github.com/FutaoSmile/springbootFramework


image.png

目录
打赏
0
0
0
0
0
分享
相关文章
编程之舞:从代码到艺术的转变
【9月更文挑战第35天】本文旨在探索编程不仅仅是技术操作的集合,更是一种创造性的艺术表达。我们将通过具体的编程示例和技巧,展示如何将代码转化为富有美感和效率的作品。文章将引导读者理解编程背后的哲学和美学原则,从而提升他们的编码技能和审美意识。
68 3
|
6月前
|
Python 控制结构:开启震撼编程之旅,犹如舞台上的精彩戏剧,让你的代码活起来!
【8月更文挑战第22天】Python的控制结构是编程的核心,包括条件判断(if-elif-else)和循环(for、while)。例如,可以用if-elif-else判断学生成绩等级,for循环计算1至10的总和,while循环实现猜数字游戏。此外,列表推导式等高级特性让操作更简洁高效。掌握这些结构能显著提升编程效率和代码质量。
68 1
代码之舞:探索编程的艺术与实践
【8月更文挑战第7天】 在数字世界的舞台上,每一行代码都是舞者的步伐,每一个算法都是编舞的旋律。本文将带领读者穿梭于编程的世界,从初学者的踌躇满志到资深开发者的从容不迫,揭示技术成长之路上的心得体会。我们将探讨如何通过持续学习、实践和反思,不仅提升技术能力,更培养对编程艺术的感悟与欣赏。
64 3
编程之舞:从代码到艺术
【8月更文挑战第30天】在数字世界的舞台上,代码不仅仅是指令的堆砌,它更像是一种语言,一种能够创造无限可能的艺术。本文将带你走进编程的世界,探索如何将枯燥的代码转化为富有创造力的艺术作品,从而开启一段技术与艺术交织的旅程。
代码之韵:寻找编程中的诗意
【5月更文挑战第11天】 在数字的严谨与逻辑的框架之下,编程往往被视为一门枯燥的技艺。然而,随着技术的不断深入与个人实践的积累,我开始领悟到编程不仅仅是冷冰冰的指令序列,它如同一种现代的文学,蕴含着独特的美学和节奏感。本文将探讨如何在编程的过程中找到那些令人着迷的“诗行”,并分享一些提升代码“艺术性”的个人感悟。
优秀程序员的学习习惯和方法你都不知道,还学什么编程
好的学习习惯和方法会让你的工作事半功倍,快来看看你还差哪些
82 0
优秀程序员的学习习惯和方法你都不知道,还学什么编程
【2023】某python语言程序设计跟学第四周内容
【2023】某python语言程序设计跟学第四周内容
99 0
【2023】某python语言程序设计跟学第二周内容
【2023】某python语言程序设计跟学第二周内容
109 0
Python编程 圣诞树教程 (附代码)程序员的浪漫
Python编程 圣诞树教程 (附代码)程序员的浪漫
1313 0