`
esffor
  • 浏览: 1353185 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

基于Ant+Velocity的简单代码生成器的思路与实现

阅读更多

在SSH项目中,我们应用了service layer模式,所以针对一个模块,它就存在pojo、dao、daoImpl、service、serviceImpl,再到struts中的action、form。假设设计是面向数据库的,针对一个数据库表,那么就要产生7个java文件,如果还要做异常处理,那么就是8个java文件。如果数据库有50个表,那么就是50*8=400个java文件。工程不小。

至于为什么要用service layer模式,论坛上已有讨论http://www.iteye.com/topic/29867

然而我们都知道,web中出现最多的操作是CURD,这400个java文件中有多少代码是重复的?几乎占了80%甚至更多。编写这样重复的代码是很枯燥无味的,而且如果是由不同人负责不同的模块的分工方式,程序员编码的风格是各不相同(虽然可能有规范约束,但是最后出来的东西还是避免不了的带有程序员个人风格的)。

所以为了节省时间和精力,便做一个程序来生成程序。
只要配置好你的项目名,你的模块名,模块路径,就可以在几秒之内完成一个模块的CURD代码,同时你可以自定义模板。

这是工具的大概设计思路:

由ant处理编译、生成目录的工作,velocity处理程序模板,contentEngine为核心处理程序。

产生的目录结构和代码路径:
模块名
--子模块1
----model
------businessobject
------dao
--------hibernate
----service
------impl
----view
------action
------form
----Exception
--子模块2
...
其中model/businessobject中是pojo和hbm.xml,这个由hibernate工具根据数据库表产生。

我们假设模块名为course,子模块名为table,类名为CourseMember。因篇幅问题,我们只看一个daoImpl的例子。

首先我们利用建立一个daoImpl的模板
ObjectDaoHibernateImpl.vm

代码
  1. ${package_Hibernate}   
  2. ${import_SQLException}   
  3. ${import_List}   
  4. ${import_HibernateCallback}   
  5. ${import_HibernateObjectRetrievalFailureException}   
  6. ${import_HibernateDaoSupport}   
  7. ${import_HibernateException}   
  8. ${import_Query}   
  9. ${import_Session}   
  10. ${import_ObjectNameDao}   
  11. ${import_ObjectName}   
  12. ${import_Finder}   
  13. ${import_Page}   
  14. ${import_Criteria}   
  15. ${import_Projections}   
  16.   
  17. /**   
  18.  * The Hibernate implementation of the <code>${ObjectName}Dao</code>.   
  19.  *    
  20.  * @author ${Author}   
  21.  * @see ${ObjectName}Dao   
  22.  */   
  23. public class ${ObjectName}DaoHibernateImpl extends HibernateDaoSupport implements ${ObjectName}Dao {   
  24.     /**   
  25.      * Default constructor.   
  26.      */   
  27.     public ${ObjectName}DaoHibernateImpl() {   
  28.         super();   
  29.     }   
  30.        
  31.     /**   
  32.      * @see ${ObjectName}Dao#save${ObjectName}(${ObjectName})   
  33.      */   
  34.     public ${ObjectName} save${ObjectName}(${ObjectName} ${objectname}) {   
  35.         this.getHibernateTemplate().save(${objectname});   
  36.         return ${objectname};   
  37.     }   
  38.        
  39.     /**   
  40.      * @see ${ObjectName}Dao#get${ObjectName}(String)   
  41.      */   
  42.     public ${ObjectName} get${ObjectName}(String id) {   
  43.         return (${ObjectName})this.getHibernateTemplate().load(${ObjectName}.class, id);   
  44.     }   
  45.        
  46.     /**   
  47.      * @see ${ObjectName}Dao#update${ObjectName}(${ObjectName})   
  48.      */   
  49.     public void update${ObjectName}(${ObjectName} ${objectname}) {   
  50.         this.getHibernateTemplate().update(${objectname});   
  51.     }   
  52.        
  53.     /**   
  54.      * @see ${ObjectName}Dao#delete${ObjectName}(${ObjectName})   
  55.      */   
  56.     public void delete${ObjectName}(${ObjectName} ${objectname}) {   
  57.         this.getHibernateTemplate().delete(${objectname});   
  58.     }   
  59.        
  60.     /**   
  61.      * @see ${ObjectName}Dao#getAll${ObjectName}s()   
  62.      */   
  63.     public List getAll${ObjectName}s() {   
  64.         return getHibernateTemplate().executeFind(new HibernateCallback() {   
  65.             public Object doInHibernate(Session session)   
  66.                 throws HibernateException, SQLException {   
  67.   
  68.                 StringBuffer sb = new StringBuffer(100);   
  69.                 //sb.append("select distinct ${objectname} ");   
  70.                 sb.append("SELECT  ${objectname} ");   
  71.                 sb.append("FROM  ${ObjectName} ${objectname} ");   
  72.                 sb.append("order by ${objectname}.id");   
  73.   
  74.                 Query query = session.createQuery(sb.toString());   
  75.                 List list = query.list() ;   
  76.   
  77.                 return list;   
  78.             }   
  79.         });        
  80.     }   
  81.        
  82.        
  83.        
  84.     public Object query(final ${ObjectName} ${objectname},   
  85.             final int pageNo, final int maxResult) {   
  86.         return getHibernateTemplate().execute(new HibernateCallback() {   
  87.             public Object doInHibernate(Session session)   
  88.                     throws HibernateException, SQLException {   
  89.                 Criteria criteria=session.createCriteria(${ObjectName}.class);   
  90.                 Criteria anothercriteria=session.createCriteria(${ObjectName}.class);   
  91.                 criteria.setProjection(Projections.rowCount());    
  92.                
  93.     //          if (!${objectname}.get${objectname}Name().equals("")   
  94.     //                  && ${objectname}.get${objectname}Name() != null) {   
  95.     //              criteria.add(Expression.ilike("contactName","%"+customerContactForm.getContactName()+"%"));   
  96.     //              anothercriteria.add(Expression.ilike("contactName","%"+customerContactForm.getContactName()+"%"));   
  97.     //          }   
  98.                 Integer count=(Integer)criteria.uniqueResult();   
  99.                 List list=anothercriteria.setFirstResult((pageNo-1)*maxResult).setMaxResults(maxResult).list();   
  100.                 Page page=new Page(count.intValue(), maxResult, pageNo);   
  101.                 return new Finder(list, page);   
  102.             }   
  103.         });   
  104.     }   
  105.        
  106.     public boolean deleteBybatch(final String[] chxSong) {   
  107.     StringBuffer cusIdList = new StringBuffer(200);   
  108.     cusIdList.append("delete from ${ObjectName} where ${objectName}No=");   
  109.         for (int i = 0; i < chxSong.length; i++) {   
  110.             if (i == 0)   
  111.                 cusIdList.append(chxSong[i]);   
  112.             else   
  113.                 cusIdList.append(" or ${objectName}No=" + chxSong[i]);   
  114.         }   
  115.         this.getSession().createQuery(cusIdList.toString()).executeUpdate();   
  116.         return true;   
  117.     }   
  118.        
  119. }   
<script type="text/javascript">render_code();</script>
声明:
1)其中${}是模板语言中的变量,变量的来源一是通过对应的.properties文件,另外是通过参数传递。
2)注释部分因是分页查询条件,这个涉及到具体字段,无法预知,所以需要在产生代码之后程序员根据查询条件自行修改。另外也涉及到个人项目的分页方法,这个根据具体情况自定义模板。

 

template.properties
公共属性文件,是所有template文件(.vm)的变量声明处,这个会在后面代码中进行设置。
对于属性文件,可有两种方式:
一是针对每一个template模板文件都建立一个属性文件,优点是在后面ant中设置的参数就少了,而且方便修改。缺点是模板文件数量增多,另外公共部分声明重复。
二是设定一个公共属性文件,将特定的变量交给参数传递。
我们这里先用公共属性文件的方式。

代码
  1. Author = Cmas R&D Team   
  2. import_Arraylist = import java.util.ArrayList;   
  3. import_List = import java.util.List;   
  4. import_Set = import java.util.Set;   
  5. import_FacesException = import javax.faces.FacesException;   
  6. import_BeanUtils = import org.apache.commons.beanutils.BeanUtils;   
  7. import_Log = import org.apache.commons.logging.Log;   
  8. import_LogFactory = import org.apache.commons.logging.LogFactory;   
  9. import_SQLException = import java.sql.SQLException;   
  10. import_HibernateCallback = import org.springframework.orm.hibernate3.HibernateCallback;   
  11. import_HibernateObjectRetrievalFailureException = import org.springframework.orm.hibernate3.HibernateObjectRetrievalFailureException;   
  12. import_HibernateDaoSupport = import org.springframework.orm.hibernate3.support.HibernateDaoSupport;   
  13. import_HibernateException = import org.hibernate.HibernateException;   
  14. import_Query = import org.hibernate.Query;   
  15. import_Session = import org.hibernate.Session;   
  16. import_Map = import java.util.Map;   
  17. import_HashMap = import java.util.HashMap;   
  18. import_Iterator = import java.util.Iterator;   
  19. import_Criteria=import org.hibernate.Criteria;   
  20. import_Projections=import org.hibernate.criterion.Projections;   
  21. import_DispatchActionSupport=import org.springframework.web.struts.DispatchActionSupport;   
  22. import_Action=import org.apache.struts.action.*;   
  23. import_HttpServletRequest=import javax.servlet.http.HttpServletRequest;   
  24. import_HttpServletResponse=import javax.servlet.http.HttpServletResponse;   
  25. import_BeanUtils=import org.apache.commons.beanutils.BeanUtils;   
  26. import_DataIntegrity=import org.springframework.dao.DataIntegrityViolationException;   

接下来是ant部分,我们编写build.xml

build.xml

代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <project name="cmas" basedir="../" default="all">  
  3.   
  4.     <!-- Project settings -->  
  5.     <property name="project.distname" value="cmas" /><!-- 设定项目名 -->  
  6.     <property name="project/operationName" value="course/table" /><!-- 设定模块名,如果有多层以“/”方式扩充,此为目录结构变量设定 -->  
  7.     <property name="project.operationName" value="course.table" /><!-- 设定模块名,如果有多层以“.”方式扩充,此为包结构变量设定 -->  
  8.     <property name="ObjectName" value="CourseMember" /><!-- 模块名类名,大写 -->  
  9.     <property name="objectName" value="courseMember" /><!-- 模块名变量名,小写 -->  
  10.   
  11.     <!-- Local system paths -->  
  12.     <property file="${basedir}/ant/build.properties" /><!-- 设定ant的一些属性,这里我们没有额外的设置,使用默认 -->  
  13.     <property file="${basedir}/${webroot.dir}/template/build.properties" />  
  14.   
  15.     <!--Save_path-->  
  16.         <!-- 建立目录结构 -->  
  17.     <mkdir dir="${basedir}/JavaSource/com/bnu/${project.distname}/${project/operationName}/model" />  
  18.     <mkdir dir="${basedir}/JavaSource/com/bnu/${project.distname}/${project/operationName}/service" />  
  19.     <mkdir dir="${basedir}/JavaSource/com/bnu/${project.distname}/${project/operationName}/view" />  
  20.         <!-- 声明目录结构变量 -->  
  21.     <property name="model.src.dir" location="${basedir}/JavaSource/com/bnu/${project.distname}/${project/operationName}/model" />  
  22.     <property name="service.src.dir" location="${basedir}/JavaSource/com/bnu/${project.distname}/${project/operationName}/service" />  
  23.     <property name="view.src.dir" location="${basedir}/JavaSource/com/bnu/${project.distname}/${project/operationName}/view" />  
  24.   
  25.     <property name="overwrite" value="false" />  
  26.     <property name="debug" value="true" />  
  27.     <property name="webroot.dir" value="${basedir}/WebContent" />  
  28.     <property name="webinf.dir" value="${webroot.dir}/WEB-INF" />  
  29.     <property name="build.dir" value="build" />  
  30.   
  31.     <!-- 模板文件的声明,这里暂时只写ObjectDaoHibernateImpl -->  
  32.     <property name="template.dir" value="${webroot.dir}/template" />  
  33.     <property name="ObjectDaoHibernateImpl.template" value="./ObjectDaoHibernateImpl.vm" />  
  34.     <property name="template.properties" value="${template.dir}/template.properties" />  
  35.         <!--设定classpath,这些包不能少-->  
  36.     <property name="classpath" value="${webinf.dir}/classes/" />  
  37.     <!-- classpath for JSF 1.1.01 -->  
  38.     <path id="compile.classpath">  
  39.         <pathelement path="${webinf.dir}/lib/hibernate3.jar" />  
  40.         <pathelement path="${webinf.dir}/lib/log4j-1.2.9.jar" />  
  41.         <pathelement path="${webinf.dir}/lib/commons-beanutils.jar" />  
  42.         <pathelement path="${webinf.dir}/lib/commons-collections.jar" />  
  43.         <pathelement path="${webinf.dir}/lib/commons-digester.jar" />  
  44.         <pathelement path="${webinf.dir}/lib/commons-logging.jar" />  
  45.         <pathelement path="${webinf.dir}/lib/jsf-api.jar" />  
  46.         <pathelement path="${webinf.dir}/lib/jsf-impl.jar" />  
  47.         <pathelement path="${webinf.dir}/lib/jstl.jar" />  
  48.         <pathelement path="${webinf.dir}/lib/standard.jar" />  
  49.         <pathelement path="${webinf.dir}/lib/log4j.jar" />  
  50.         <pathelement path="${webinf.dir}/lib/velocity-1.4.jar" />  
  51.         <pathelement path="${webinf.dir}/lib/velocity-1.4-dev.jar" />  
  52.         <pathelement path="${webinf.dir}/classes" />  
  53.         <pathelement path="${classpath.external}" />  
  54.         <pathelement path="${classpath}" />  
  55.     </path>  
  56.   
  57.     <!--*****************Build_Dao_Hibernate_Impl*开始创建daoImpl**********************-->  
  58.     <!-- define your folder for deployment -->  
  59.     <property name="build_daoimpl.dir" value="build_daoimpl" />  
  60.   
  61.     <!-- Check timestamp on files -->  
  62.     <target name="build_daoimpl_prepare">  
  63.         <tstamp />  
  64.     </target>  
  65.   
  66.     <!-- Copy any resource or configuration files -->  
  67.     <target name="build_daoimpl_resources">  
  68.         <copy todir="${webinf.dir}/classes" includeEmptyDirs="no">  
  69.             <fileset dir="JavaSource">  
  70.                 <patternset>  
  71.                     <include name="**/*.conf" />  
  72.                     <include name="**/*.properties" />  
  73.                     <include name="**/*.xml" />  
  74.                 </patternset>  
  75.             </fileset>  
  76.         </copy>  
  77.     </target>  
  78.   
  79.     <target name="build_daoimpl_init">  
  80.         <!-- Create the time stamp -->  
  81.         <tstamp />  
  82.         <!-- Create the build directory structure used by compile -->  
  83.         <mkdir dir="${model.src.dir}/dao/hibernate" />  
  84.     </target>  
  85.   
  86.     <!-- Normal build of application -->  
  87.     <target name="build_daoimpl_compile" depends="build_daoimpl_prepare,build_daoimpl_resources,build_daoimpl_init">  
  88.         <javac srcdir="${basedir}/JavaSource/com/bnu/exception/" destdir="${webinf.dir}/classes/">  
  89.             <classpath refid="compile.classpath" />  
  90.         </javac>  
  91.   
  92.         <!--编译核心java文件contentEngine,这个路径根据具体情况设定,也可以在前面对其进行统一声明-->  
  93.         <javac srcdir="${basedir}/JavaSource/com/bnu/tools" destdir="${webinf.dir}/classes/">  
  94.             <classpath refid="compile.classpath" />  
  95.         </javac>  
  96.                 <!--运行contentEngine,参数设定-->  
  97.         <java classname="com.bnu.tools.ContentEngine">  
  98.             <classpath refid="compile.classpath" />  
  99.             <arg value="DaoImpl" />  
  100.             <arg value="${template.dir}" />  
  101.             <arg value="${template.properties}" />  
  102.             <arg value="${ObjectDaoHibernateImpl.template}" />  
  103.             <arg value="package com.bnu.${project.distname}.${project.operationName}.model.dao.hibernate;" />  
  104.             <arg value="import com.bnu.${project.distname}.${project.operationName}.model.dao.${ObjectName}Dao;" />  
  105.             <arg value="import com.bnu.${project.distname}.${project.operationName}.model.businessobject.${ObjectName};" />  
  106.             <arg value="${objectName}" />  
  107.             <arg value="${ObjectName}" />  
  108.             <arg value="${model.src.dir}/dao/hibernate" />  
  109.             <arg value="${ObjectName}DaoHibernateImpl.java" />  
  110.         </java>  
  111.     </target>  
  112.   
  113.     <!-- Remove classes directory for clean build -->  
  114.     <target name="build_daoimpl_clean" description="Prepare for clean build">  
  115.         <delete dir="${webinf.dir}/classes" />  
  116.         <mkdir dir="${webinf.dir}/classes" />  
  117.     </target>  
  118.   
  119.     <!-- Build entire project -->  
  120.     <target name="build_daoimpl_build" depends="build_daoimpl_prepare,build_daoimpl_compile" />  
  121.     <target name="build_daoimpl_rebuild" depends="build_daoimpl_clean,build_daoimpl_prepare,build_daoimpl_compile" />  
  122.   
  123.     <target name="build_daoimpl" depends="build_daoimpl_build">  
  124.         <delete file="${build_daoimpl.dir}/${project.distname}.war" />  
  125.         <delete dir="${build_daoimpl.dir}/${project.distname}" />  
  126.     </target>  
  127.   
  128.     <target name="clean" description="clean">  
  129.         <delete dir="${build.dir}" />  
  130.         <delete dir="${webinf.dir}/classes
分享到:
评论

相关推荐

    velocity 入门文档及应用源码,很适合做自动代码生成

    入门文档及应用源码,很适合做自动代码生成 包括:Velocity的中文指南\ velocity中文手册\ \基于Ant+Velocity的简单代码生成器的思路与实现

    基于ant的代码生成器

    该代码生成工具说明: 1.实现模板的灵活配置; 2.支持DB2、MySQL、HSQL、PostgreSQL、SQLServer2005、Oracle...3.建议先用已有的模板进行简单代码的生成测试,待掌握后可进行灵活配置。 快速的开发,其实就是这么简单。

    FCG 架构代码生成器

    所以准确的讲:FCG不是个代码生成器,而是用来开发代码生成器的基础平台. &lt;br/&gt; FCG相比其他生成器,有很多不一样的东西.下面列出FCG几点特性. &lt;br/&gt;1. FCG采用plugin设计体系,一个具体软件架构的生成...

    Maven权威指南 很精典的学习教程,比ANT更好用

    站点生成和报告 (Site Generation and Reporting) 3.6. 小结 4. 定制一个Maven项目 4.1. 介绍 4.1.1. 下载本章样例 4.2. 定义Simple Weather项目 4.2.1. Yahoo! Weather RSS 4.3. 创建Simple Weather...

    hibernate 教程

    基于Velocity的渲染器/生成器(Velocity based renderer/generator) 15.3. 映射文件生成器(Mapping File Generation) 15.3.1. 运行此工具 16. 示例:父子关系(Parent Child Relationships) 16.1. 关于...

    hibernate

    基于Velocity的渲染器/生成器(Velocity based renderer/generator) 15.3. 映射文件生成器(Mapping File Generation) 15.3.1. 运行此工具 16. 示例:父子关系(Parent Child Relationships) 16.1. 关于...

    Spring-Reference_zh_CN(Spring中文参考手册)

    5. 校验,数据绑定,BeanWrapper,与属性编辑器 5.1. 简介 5.2. 使用Spring的Validator接口进行校验 5.3. 从错误代码到错误信息 5.4. Bean处理和BeanWrapper 5.4.1. 设置和获取属性值以及嵌套属性 5.4.2. 内建的...

    Pamda-开源

    Pamda是MDA工具(UML到代码生成器)。 它使用UML API解析XMI,因此,与某些其他MDA工具不同,它对XMI扩展很宽容。 作为Ant任务实现,并使用Velocity模板引擎。 经过Enterprise Architect生产的XMI的测试。

    forcevelocity-开源

    将Salesforce Force.com API集成到Apache Velocity中。 提供在模板语言中使用的Ant任务和许多Velocity工具。 可以编写模板以从“自定义对象”元数据生成代码,HTML,数据加载器脚本等。

    velogen-开源

    VeloGen是用Java编写的自定义源生成器,它使用velocity和antlr。 Antlr解析的AST语法被包装并放入Velocity上下文中。 用于生成源的模板以速度模板语言(VTL)编写。 从ANT任务中调用它。

Global site tag (gtag.js) - Google Analytics