• Java 使用Velocity引擎生成代码


    Java 使用Velocity引擎生成代码

    原理

    •  
    • 配置数据源信息(包括表名)

    • 读取数据表字段信息:列名、类型、字段注释、表注释

    • 编写代码模板,并将该模板加载到内存

    • 根据模板所需,组装Velocity引擎渲染所需字段Map

    • 创建Velocity上下文,将代码模板和替换字段传入

    • velocity上下文创建引擎,执行merge合并替换并将最终代码写入文件

    实战

    • 通过maven构建项目,引入依赖:

      1.    velocity
      2.    org.apache.velocity
      3.    
      4.        
      5.            commons-collections
      6.            commons-collections
      7.        
      8.    
      9.    org.apache.velocity
      10.    velocity-engine-core

    • 在resources/templates/codegenerator目录下面编写代码模板:

    • vo:

      1. package ${basePackage}.module.${modulePackage}.domain.vo;
      2. import lombok.Data;
      3. #foreach ($dtoImport in $dtoImports)
      4. $dtoImport
      5. #end
      6. import com.fasterxml.jackson.annotation.JsonFormat;
      7. import io.swagger.annotations.ApiModelProperty;
      8. /**
      9. * [ ${tableDesc} ]
      10. *
      11. * @author ${author}
      12. * @version 1.0
      13. * @company ${company}
      14. * @copyright (c) ${company}Inc. All rights reserved.
      15. * @date ${date}
      16. * @since JDK1.8
      17. */
      18. @Data
      19. public class ${moduleClass}VO {
      20. #foreach ($column in $columnList)
      21. #if($column.fieldType == 'Date')
      22.    @ApiModelProperty("${column.columnDesc}")
      23.    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
      24.    private $column.fieldType $column.fieldName;
      25. #else
      26.    @ApiModelProperty("${column.columnDesc}")
      27.    private $column.fieldType $column.fieldName;
      28. #end
      29. #end
      30. }

    • SERVICE:

      1. package ${basePackage}.module.${modulePackage}.service;
      2. import com.baomidou.mybatisplus.core.metadata.IPage;
      3. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
      4. import ${basePackage}.common.domain.PageResultDTO;
      5. import ${basePackage}.common.domain.ResponseDTO;
      6. import ${basePackage}.module.${modulePackage}.dao.${moduleClass}Dao;
      7. import ${basePackage}.module.${modulePackage}.domain.dto.${moduleClass}AddDTO;
      8. import ${basePackage}.module.${modulePackage}.domain.dto.${moduleClass}UpdateDTO;
      9. import ${basePackage}.module.${modulePackage}.domain.dto.${moduleClass}QueryDTO;
      10. import ${basePackage}.module.${modulePackage}.domain.entity.${moduleClass}Entity;
      11. import ${basePackage}.module.${modulePackage}.domain.vo.${moduleClass}VO;
      12. import ${basePackage}.module.${modulePackage}.domain.vo.${moduleClass}ExcelVO;
      13. import ${basePackage}.util.SmartPageUtil;
      14. import ${basePackage}.util.SmartBeanUtil;
      15. import org.springframework.beans.factory.annotation.Autowired;
      16. import org.springframework.stereotype.Service;
      17. import org.springframework.transaction.annotation.Transactional;
      18. import java.util.List;
      19. /**
      20. * [ ${tableDesc} ]
      21. *
      22. * @author ${author}
      23. * @version 1.0
      24. * @company ${company}
      25. * @copyright (c) ${company}Inc. All rights reserved.
      26. * @date ${date}
      27. * @since JDK1.8
      28. */
      29. @Service
      30. public class ${moduleClass}Service {
      31.    @Autowired
      32.    private ${moduleClass}Dao ${moduleVar}Dao;
      33.    /**
      34.     * 根据id查询
      35.     */
      36.    public ${moduleClass}Entity getById(Long id){
      37.        return  ${moduleVar}Dao.selectById(id);
      38.   }
      39.    /**
      40.     * 分页查询
      41.     * @author ${author}
      42.     * @date ${date}
      43.     */
      44.    public ResponseDTO> queryByPage(${moduleClass}QueryDTO queryDTO) {
      45.        Page page = SmartPageUtil.convert2QueryPage(queryDTO);
      46.        IPage<${moduleClass}VO> voList = ${moduleVar}Dao.queryByPage(page, queryDTO);
      47.        PageResultDTO<${moduleClass}VO> pageResultDTO = SmartPageUtil.convert2PageResult(voList);
      48.        return ResponseDTO.succData(pageResultDTO);
      49.   }
      50.    /**
      51.     * 添加
      52.     * @author ${author}
      53.     * @date ${date}
      54.     */
      55.    public ResponseDTO add(${moduleClass}AddDTO addDTO) {
      56.        ${moduleClass}Entity entity = SmartBeanUtil.copy(addDTO, ${moduleClass}Entity.class);
      57.        ${moduleVar}Dao.insert(entity);
      58.        return ResponseDTO.succ();
      59.   }
      60.    /**
      61.     * 编辑
      62.     * @author ${author}
      63.     * @date ${date}
      64.     */
      65.    @Transactional(rollbackFor = Exception.class)
      66.    public ResponseDTO update(${moduleClass}UpdateDTO updateDTO) {
      67.        ${moduleClass}Entity entity = SmartBeanUtil.copy(updateDTO, ${moduleClass}Entity.class);
      68.        ${moduleVar}Dao.updateById(entity);
      69.        return ResponseDTO.succ();
      70.   }
      71.    /**
      72.     * 删除
      73.     * @author ${author}
      74.     * @date ${date}
      75.     */
      76.    @Transactional(rollbackFor = Exception.class)
      77.    public ResponseDTO deleteByIds(List idList) {
      78.        ${moduleVar}Dao.deleteByIdList(idList);
      79.        return ResponseDTO.succ();
      80.   }
      81.    /**
      82.     * 查询全部导出对象
      83.     * @author ${author}
      84.     * @date ${date}
      85.     */
      86.    public List<${moduleClass}ExcelVO> queryAllExportData(${moduleClass}QueryDTO queryDTO) {
      87.        return ${moduleVar}Dao.queryAllExportData( queryDTO);
      88.   }
      89.    /**
      90.     * 批量查询导出对象
      91.     * @author ${author}
      92.     * @date ${date}
      93.     */
      94.    public List<${moduleClass}ExcelVO> queryBatchExportData(List idList) {
      95.        return ${moduleVar}Dao.queryBatchExportData(idList);
      96.   }
      97. }

    • Mapper:

      1. "1.0" encoding="UTF-8"?>
      2. "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
      3. "${basePackage}.module.${modulePackage}.dao.${moduleClass}Dao">
      4.    "${moduleClass}VO" type="${basePackage}.module.${modulePackage}.domain.vo.${moduleClass}VO">
      5.    "${moduleClass}ExcelVO" type="${basePackage}.module.${modulePackage}.domain.vo.${moduleClass}ExcelVO">
      6.    
      7.    
      8.    
      9.    "deleteById">
      10.        delete from ${tableName} where id = #{id}
      11.    
      12.    "deleteByIdList">
      13.        delete from ${tableName} where id in
      14.        "idList" open="(" close=")" separator="," item="item">
      15.            #{item}
      16.        
      17.    

    • 查询表信息:

      1. <select id="selectTableDesc" resultType="String">
      2.   select
      3.       table_comment
      4.   from information_schema.tables
      5.   where table_schema = (select database()) and table_name = #{tableName}
      6. </select>
      7. <select id="selectTableColumn" resultMap="ColumnDTO">
      8.   select
      9.       column_name as columnName,
      10.       data_type as columnType,
      11.       column_comment as columnDesc
      12.   from information_schema.columns
      13.   where table_schema = (select database()) AND table_name = #{tableName} order by ordinal_position
      14. </select>

    • 加载模板、组装数据

      1. public Map codeTemplates(String moduleClass, String basePackage, String modulePackage) {
      2.    String basePath = basePackage.replaceAll("\\.", File.separator );
      3.    String modulePath = modulePackage.replaceAll("\\.", File.separator );
      4.    String javaPackagePath = "java" + File.separator + basePath + File.separator + modulePath + File.separator;
      5.    String xmlPackagePath = "mapper" + File.separator + modulePath + File.separator;
      6.    String frontPackagePath = "web" + File.separator;
      7.    Map templateMap = new HashMap<>();
      8.    //后端
      9.    templateMap.put("templates/codegenerator/java/Controller.java.vm", javaPackagePath + "controller" + File.separator + moduleClass + "Controller.java" );
      10.    templateMap.put("templates/codegenerator/java/Dao.java.vm", javaPackagePath + "dao" + File.separator + moduleClass + "Dao.java" );
      11.    templateMap.put("templates/codegenerator/java/Dao.xml.vm", xmlPackagePath + moduleClass + "Mapper.xml" );
      12.    templateMap.put("templates/codegenerator/java/AddDTO.java.vm", javaPackagePath + "domain" + File.separator + "dto" + File.separator + moduleClass + "AddDTO.java" );
      13.    templateMap.put("templates/codegenerator/java/UpdateDTO.java.vm", javaPackagePath + "domain" + File.separator + "dto" + File.separator + moduleClass + "UpdateDTO.java" );
      14.    templateMap.put("templates/codegenerator/java/Entity.java.vm", javaPackagePath + "domain" + File.separator + "entity" + File.separator + moduleClass + "Entity.java" );
      15.    templateMap.put("templates/codegenerator/java/VO.java.vm", javaPackagePath + "domain" + File.separator + "vo" + File.separator + moduleClass + "VO.java" );
      16.    templateMap.put("templates/codegenerator/java/ExcelVO.java.vm", javaPackagePath + "domain" + File.separator + "vo" + File.separator + moduleClass + "ExcelVO.java" );
      17.    templateMap.put("templates/codegenerator/java/QueryDTO.java.vm", javaPackagePath + "domain" + File.separator + "dto" + File.separator + moduleClass + "QueryDTO.java" );
      18.    templateMap.put("templates/codegenerator/java/Service.java.vm", javaPackagePath + "service" + File.separator + moduleClass + "Service.java" );
      19.    //前端
      20.    String webPackageName = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, moduleClass).replaceAll("_", "-" );
      21.    templateMap.put("templates/codegenerator/web/Api.js.vm", frontPackagePath + "api" + File.separator + webPackageName + ".js" );
      22.    templateMap.put("templates/codegenerator/web/Router.js.vm", frontPackagePath + "router" + File.separator + webPackageName + ".js" );
      23.    templateMap.put("templates/codegenerator/web/List.vue.vm", frontPackagePath + webPackageName + File.separator + webPackageName + "-list.vue" );
      24.    templateMap.put("templates/codegenerator/web/ListForm.vue.vm", frontPackagePath + webPackageName + File.separator + "components" + File.separator + webPackageName + "-list-form.vue" );
      25.    return templateMap;
      26. }

      1. Properties p = new Properties();
      2. p.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
      3. p.put("directive.foreach.counter.name", "velocityCount");
      4. p.put("directive.foreach.counter.initial.value", "1");
      5. Velocity.init(p);
      6. Map map = new HashMap<>();
      7. map.put("company", codeGenerator.getCompany());
      8. map.put("tableName", codeGenerator.getTableName());
      9. map.put("basePackage", basePackage);
      10. map.put("modulePackage", modulePackage);
      11. map.put("moduleClass", moduleClass);
      12. map.put("tableDesc", tableDesc);
      13. map.put("author", author);
      14. map.put("date", date);
      15. map.put("moduleVar", moduleVar);
      16. map.put("columnList", columnList);
      17. map.put("queryFieldList", queryFieldList);
      18. map.put("queryImports", queryImports);
      19. map.put("dtoImports", dtoImports);
      20. map.put("entityImports", entityImports);
      21. map.put("webModuleName", CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, moduleClass).replaceAll("_", "-"));
      22. map.put("upperCamel", CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_CAMEL, moduleClass));
      23. //前端的变量
      24. map.put("ViewUIMessage", "$Message");
      25. map.put("VueRefs", "$refs");

    • 创建Velocity上下文,生成代码

      1. VelocityContext context = new VelocityContext(map);
      2. private void codeGenerator(VelocityContext context, Map codeTemplates) throws Exception {
      3.    String projectPath = getOutputDir();
      4.    Velocity.setProperty("input.encoding", "UTF-8");
      5.    Velocity.setProperty("output.encoding", "UTF-8");
      6.    for (Entry entry : codeTemplates.entrySet()) {
      7.        String template = entry.getKey();
      8.        String filePath = projectPath + entry.getValue();
      9.        String fileName = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
      10.        String fileDir = filePath.replace(fileName, "");
      11.        File directory = new File(fileDir);
      12.        if (!directory.exists()) {
      13.            directory.mkdirs();
      14.       }
      15.        FileWriter writer;
      16.        try {
      17.            writer = new FileWriter(filePath);
      18.            Template tpl = Velocity.getTemplate(template, "UTF-8");
      19.            tpl.merge(context, writer);
      20.            writer.flush();
      21.            writer.close();
      22.       } catch (Exception e) {
      23.            log.error("", e);
      24.       }
      25.   }
      26. }

  • 相关阅读:
    I2C3挂载wm8960音频芯片竟如此简单
    python实现批量数据库数据插入
    LeetCode每日一题——698. 划分为k个相等的子集
    分库分表利器——shardingJdbc
    Linux下七种文件类型、文件属性及其查看方法
    阿里云免费SSL证书过期替换
    Boost获取当前时间并格式化为字符串
    数图互通高校高校房产管理信息系统如何管理周转房?
    Java8新特性
    如何做bug分析 ?bug分析什么 ? 为什么要做bug分析 ?
  • 原文地址:https://blog.csdn.net/Andrew_Chenwq/article/details/126879948