• 告别无止境的增删改查:Java代码生成器


    对于一个比较大的业务系统,我们总是无止境的增加,删除,修改,粘贴,复制,想想总让人产生一种抗拒的心里。那有什么办法可以在正常的开发进度下自动生成一些类,配置文件,或者接口呢?

    有感于马上要做个比较大的业务系统,想到那无止境的增删改查、粘贴复制,顿时脑后升起一阵凉风。于是想到个找或者写一个Java代码的生成器,这样在正常开发进度下,也能余下更多的时间去做些别的事情。

    闲话少说,首先总结下需求:

    我需要的这个工具能够读取数据库表结构,通过对字段类型、名称等分析得到需要的各种变量,根据模板生成相应的pojo类、hibernate的xml配置文件、dao和service的接口和类。

    需求看起来很简单,但是一是没搞过这样的小工具,二是技术不过关,所以还是想到了找找有没有开源的代码拿过来根据自己的需求改。

    于是找到了rapid-generator这个开源工具,同学们可以下载rapid-generator直接使用,根据自己的需求写好模板就行了。

    由于自己项目中的特殊情况和公司规范等因素,另外也是想学习下别人的设计,所以我对源码进行了删减和功能的修改。

    来看下主要的类:

    Table:根据表结构建立的对象。

    Column:根据表中每列建立的对象。

    Generator:生成器核心类,主要负责根据表对象和读取FreeMarker模板生成最后的java代码文件。

    GeneratorControl:控制生成过程等的一些参数,例如文件是否覆盖、文件编码等。

    GeneratorProperties:读取配置文件的类,配置文件包括数据库连接信息和一些基本的参数配置。

    下面来看一下模板的编写:

    pojo模板:

    1. <#include "/java_copyright.include">  
    2. <#assign className = table.className>     
    3. <#assign classNameLower = className?uncap_first>   
    4. package ${basepackage}.pojo.${mpackage}.${table.classNameFirstLower};  
    5.  
    6. <#include "/java_imports.include">  
    7. import com.linkage.agri.pojo.base.BaseEntity;  
    8.  
    9. public class ${className} extends BaseEntity {  
    10.     private static final long serialVersionUID = 5454155825314635342L;  
    11.       
    12.     <#list table.columns as column>  
    13.     /**  
    14.      * ${column.remarks}  
    15.      */ 
    16.     private ${column.simpleJavaType} ${column.columnNameLower};  
    17.     </#list>  
    18.  
    19. <@generateJavaColumns/>  
    20.  
    21. <#macro generateJavaColumns>  
    22.     <#list table.columns as column>  
    23.         <#if column.isDateTimeColumn>  
    24.     public String get${column.columnName}String() {  
    25.         return DateConvertUtils.format(get${column.columnName}(), FORMAT_${column.constantName});  
    26.     }  
    27.     public void set${column.columnName}String(String ${column.columnNameLower}) {  
    28.         set${column.columnName}(DateConvertUtils.parse(${column.columnNameLower}, FORMAT_${column.constantName},${column.simpleJavaType}.class));  
    29.     }  
    30.         </#if>      
    31.     public void set${column.columnName}(${column.simpleJavaType} ${column.columnNameLower}) {  
    32.         this.${column.columnNameLower} = ${column.columnNameLower};  
    33.     }  
    34.       
    35.     public ${column.simpleJavaType} get${column.columnName}() {  
    36.         return this.${column.columnNameLower};  
    37.     }  
    38.     </#list>  
    39. </#macro> 

    FreeMarker的基本语法可以看下FreeMarker中文手册。

    ${}可以引用很多变量,这些变量包括:环境变量、table对象、配置变量等,这些变量都装在一个map里,如果自己有特殊需求,当然可以修改源码来装载更多的变量值。

    注意:当变量为对象时,访问对象的属性是通过get方法来访问的。例如${table.classNameFirstLower},是引用 table对象的getNameFirstLower()方法,即使table对象中没有nameFirstLower这个属性也能够引用。

    再看下我写的dao的模板:

    1. <#include "/java_copyright.include">  
    2. <#assign className = table.className>     
    3. <#assign classNameLower = className?uncap_first>     
    4. package ${basepackage}.dao.${mpackage}.${table.classNameFirstLower};  
    5.  
    6. import java.math.BigDecimal;  
    7. import java.util.List;  
    8. import java.util.Map;  
    9.  
    10. import com.linkage.agri.dao.base.AbstractHibernateDAO;  
    11. import com.linkage.agri.exception.DAOException;  
    12. import ${basepackage}.pojo.${mpackage}.${classNameLower}.${className};  
    13.  
    14. <#include "/java_imports.include">  
    15.  
    16. public Class ${className}DAOImpl extends AbstractHibernateDAO implements ${className}DAO  
    17. {  
    18.     /**  
    19.      * <query all>  
    20.      * @param paramMap  
    21.      * @param orderMap  
    22.      * @param pageNum  
    23.      * @param pageSize  
    24.      * @return  
    25.      * @throws DAOException  
    26.      */ 
    27.     @SuppressWarnings 
    28.     public List<${className}> queryList${className}ByAttr(Map<String, Object> paramMap, Map<String, String> orderMap, int pageNum,  
    29.         int pageSize)  
    30.         throws DAOException  
    31.     {  
    32.         return super.listInstances(${className}.class, paramMap, orderMap, pageNum, pageSize);  
    33.     }  
    34.       
    35.     /**  
    36.      *   
    37.      * <find one by id>  
    38.      * @param serial  
    39.      * @throws DAOException  
    40.      */ 
    41.     public ${className} find${className}By${table.pkColumn.columnName}(${table.pkColumn.simpleJavaType} ${table.pkColumn.columnNameFirstLower})  
    42.         throws DAOException  
    43.     {  
    44.         return (${className})super.findById(${className}.class, ${table.pkColumn.columnNameFirstLower});  
    45.     }  
    46.       
    47.     /**  
    48.      *   
    49.      * <save one>  
    50.      * @param ${table.classNameFirstLower}  
    51.      * @throws DAOException  
    52.      */ 
    53.     public ${table.pkColumn.simpleJavaType} save${className}(${className} ${table.classNameFirstLower})  
    54.         throws DAOException  
    55.     {  
    56.         return (${table.pkColumn.simpleJavaType})super.saveInstance(${table.classNameFirstLower});  
    57.     }  
    58.       
    59.     /**  
    60.      *   
    61.      * <update one>  
    62.      * @param ${table.classNameFirstLower}  
    63.      * @throws DAOException  
    64.      */ 
    65.     public void update${className}(${className} ${table.classNameFirstLower})  
    66.         throws DAOException  
    67.     {  
    68.         super.updateInstance(${className});  
    69.     }  
    70.       
    71.     /**  
    72.      * <check one is have?>  
    73.      * @param paramMap  
    74.      * @return  
    75.      * @throws DAOException  
    76.      */ 
    77.     public boolean check${className}IsHaveByAttr(Map<String, Object> paramMap)  
    78.         throws DAOException  
    79.     {  
    80.         StringBuffer sqlBuffer = new StringBuffer();  
    81.         sqlBuffer.append("SELECT COUNT(*) FROM ${table.sqlName} T ");  
    82.         sqlBuffer.append("WHERE T.${table.pkColumn.sqlName} = ? ");  
    83.           
    84.         BigDecimal big = (BigDecimal)super.findUniqueResultBySQLWithParams(sqlBuffer.toString(), paramMap.get("${table.pkColumn.columnNameFirstLower}"));  
    85.         return big.intValue() > 0 ? false : true;  
    86.     }  
    87.       
    88.     /**  
    89.      * <update some>  
    90.      * @param ${table.classNameFirstLower}List  
    91.      * @return  
    92.      * @throws DAOException  
    93.      */ 
    94.     public void update${className}Batch(List<${className}> ${table.classNameFirstLower}List)  
    95.         throws DAOException  
    96.     {  
    97.         super.updateBatchInstance(${table.classNameFirstLower}List);  
    98.     }  
    99.       
    100.     /**  
    101.      *   
    102.      * <delete one>  
    103.      * @param ${table.classNameFirstLower}  
    104.      * @throws DAOException  
    105.      */ 
    106.     public void delete${className}(${className} ${table.classNameFirstLower})  
    107.         throws DAOException  
    108.     {  
    109.         super.deleteInstance(${table.classNameFirstLower});  
    110.     }  
    111.  

    建立模板是能否解决自己问题的关键,在摸索出门道以后写模板变的十分简单。其实原理很简单,就是用一系列占位符来替换实际的变量值。

    模板路径可以按照实际项目中的路径来拜访,生成器可以读取某个路径下所有模板进行生成,结果如下图:

    接口和实现:

    就说这么多吧,感兴趣的可以研究下这个工具的源码,也DIY出一套自己代码生成工具。不感兴趣的直接写模板就能用。

    我只是走在路上,偶尔驻足观赏,偶尔回头看看。

  • 相关阅读:
    Js 作用域链
    JS 上下文模式
    javascript
    HTTP概念进阶
    JavaScript运行机制详解
    浅谈循环中setTimeout执行顺序问题
    Js 运行机制 (重点!!)
    javascript
    jQuery 知识点总结
    Educational Codeforces Round 87 (Rated for Div. 2)
  • 原文地址:https://www.cnblogs.com/firstdream/p/5475025.html
Copyright © 2020-2023  润新知