Java代码生成器:Codgen

jopen 11年前

1、什么是codgen?

Codgen是一个基于数据库元数据模型,使用freemarker模板引擎来构建输出的代码生成器。freemarker的数据模型结构通常来说都是一个Map树状结构模型,codgen也不例外,它的数据模型这棵树的根节点一般包含一个TableModel(表数据模型)对象。TableModel顾名思义就是由一张数据库表的元数据信息组成的一个数据模型,有了这个数据模型,再加上一套使用freemarker编写的多层架构模板,就可以生成一套基于这个表的多层架构代码文件。

1.1 codgen的数据模型

虽然说codgen通常需要包含一个TableModel来生成基于某张数据库表的一系列代码文件,但是可以动态去修改这些数据模型的内容,包括增加、替换和移除这棵数据模型树的任一个节点。简而言之,只要保证被解析的模板引用到的那些数据模型存在即可。

1.2 codgen的模板

codgen的模板支持两种格式,一种是text(文本格式);另一种是file(文件格式)。

1.3 codgen的输出

Codgen的输出和模板一样,也支持两种输出格式,一种是text(文本格式);另一种是file(文件格式)。

2、如何使用codgen

2.1 下载最新的codgen.jar及其依赖包

  由于codgen不是一个独立的项目,本着不重新发明轮子的原则,依赖于一些比较流行的开源框架。因此除了需要下载最新的codgen.jar包文件以外,还要下载以下jar文件:

  • commons-lang.jar 或以上兼容版本
  • commons-logging.jar或以上兼容版本
  • log4j-1.2.14或以上兼容版本
  • freemarker-2.3.13或以上兼容版本
除了以上4个必须依赖的开源包以外,由于codgen的TableModel元数据是通过JDBC来获取的,还需要下载对应数据库方言的JDBC驱动包,比如SQLServer2005的JDBC驱动包是sqljdbc.jar。目前codgen默认只支持Oracle10g\SQLServer2000 \SQLServer2005三种数据库版本。但是可以通过扩展实现codgen提供的DbProvider接口来支持更多的数据库版本。
  • Oracle10g的JDBC驱动包:ojdbc14.jar
  • SQLServer2000的JDBC驱动包:msbase.jar、mssqlserver.jar和msutil.jar
  • SQLServer2005的JDBC驱动包:sqljdbc.jar

2.2 编写codgen配置文件

虽然不使用配置文件的方式也可以实现整个代码的构建操作,但是为了减少使用代码的编写量及方便日后维护,建议使用配置文件来声明构建所依赖的一些信息,譬如 ‘数据模型’变量声明,‘输出模型’变量声明,以及数据库信息提供者等一些可以与代码分离的配置信息。以下就是一段比较完整的配置文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE codgen-config PUBLIC "-//Apache Software Foundation//DTD Tengen Configuration 1.0//EN" "com/bcs/codgen/resources/codgen-config_1_0.dtd"> <codgen-config>         <project name="AOWork" label="工程验收" outputEncoding="GBK" isDefault="true" extends="defaultProject">                 <dbProvider class="com.bcs.codgen.service.impl.Sql2005Provider">                         <jdbcConfig>                                 <driver>com.microsoft.sqlserver.jdbc.SQLServerDriver</driver>                                 <url>jdbc:sqlserver://127.0.0.1\SQL2005;DatabaseName=MUCM_DG;selectMethod=cursor</url>                                 <user>sa</user>                                 <password>sa</password>                         </jdbcConfig>                         <columnHandler class="com.bcs.codgen.service.impl.DataTypeConverterForJava"/>                 </dbProvider>                                   <dataModel name="templateDirectory">template/AOWork</dataModel>                 <dataModel name="outputDirectory">D:/QtoneProject/TengenCode/${copyright.author}/${projectName}</dataModel>                 <dataModel name="NamespaceModel" >com.qtone.aow.model.${groupName}</dataModel>                 <dataModel name="NamespaceParam">com.qtone.aow.model.${groupName}</dataModel>                 <dataModel name="NamespaceDao">com.qtone.aow.dao.${groupName}</dataModel>                 <dataModel name="NamespaceDaoImpl">com.qtone.aow.dao.${groupName}</dataModel>                 <dataModel name="NamespaceBll">com.qtone.aow.bll.${groupName}</dataModel>                 <dataModel name="NamespaceBllImpl">com.qtone.aow.bll.${groupName}</dataModel>                 <dataModel name="NamespaceApp">com.qtone.aow.app.${groupName}</dataModel>                                                   <template name="tDao" type="file">dao.ftl</template>                                   <output name="Model" type="text" templateText="${defaultJavaModel}" ></output>                 <output name="Param" type="text" templateFile="Param.ftl" ></output>                 <output name="Dao" type="text" templateName="tDao"></output>                 <output name="DaoImpl" type="text"></output>                 <output name="Bll" type="file" templateFile="template/AOWork/Bll">${outputDirectory}/Bll.java</output>                 <output name="BllImpl" type="file">${outputDirectory}/BllImpl.java</output>         </project> </codgen-config>

2.3 编写客户端调用代码

2.3.1 Web环境下使用示例(以struts为例)
        private ActionForward generate(ActionMapping mapping, GenerateForm generateForm,                          HttpServletRequest request, HttpServletResponse response) {                  BuildModel buildModel = generateForm.getBuildModel();                  //取得指定项目名称的配置信息                  ProjectConfig projectConfig = ProjectConfigHelper                  .getProjectConfig(this.getServlet().getServletContext()                                  , buildModel.getProjectName());                           //实例化一个项目构建配置对象                  ProjectBuildConfig buildConfig = new ProjectBuildConfig(projectConfig);                  //设置数据库表名称(Sys_UserInfo)                  buildConfig.setTableName(buildModel.getTableName());                   //设置表标签(如:用户信息)                  buildConfig.setTableLabel(buildModel.getTableLabel());                   //设置分组名称(通常为表 名称的前缀,如:Sys)                  buildConfig.setGroupName(buildModel.getGroupName());                   //设置模块名称(如:UserInfo)                  buildConfig.setModuleName(buildModel.getModuleName());                   //设置版本的创建人                  buildConfig.getCopyright().setAuthor(buildModel.getAuthor());                   //由一个构建配置对象实例化一个代码生成器对象                  Builder builder = new CodeBuilder(buildConfig);                   builder.build(); //执行构建操作                                    return mapping.findForward(INPUT_FORWARD);          }

在 web环境下,codgen是这样去寻找配置文件来加载的:如果web.xml配置了名称为“codgen.config”的上下文初始化参数(相对于 WEB-INF目录下的文件路径,多个文件名以英文逗号分隔);如果未配置该参数,则默认读取类路径根目录下的"codgen-config.xml",所以在这种情况下请确保src目录下存在codgen-config.xml文件。

2.3.2 非web环境下使用示例
        public static void main(String[] args) {                  //取得默认的项目配置信息,在非web环境下调用传递参数null即可,但配置文件必须是src目录下的codgen-config.xml                  ProjectConfig projectConfig = ProjectConfigHelper.getDefaultProjectConfig(null);                  ProjectBuildConfig buildConfig = new ProjectBuildConfig(projectConfig);                  buildConfig.setTableName("Sys_UserInfo");                  //buildConfig.setTableLabel("用户信息"); //不设置默认为表注释,表注释为空时则使用表名称                  //buildConfig.setGroupName("System");  //不设置默认为Sys                  //buildConfig.setModuleName("UserInfo"); //不设置默认为UserInfo                  //buildConfig.getCopyright().setAuthor("黄天政"); //不设置默认为当前计算机用户名                                    Builder builder = new CodeBuilder(buildConfig);                  Map<String,OutputModel> omMap = builder.build();                  for(Entry<String,OutputModel> entry : omMap.entrySet()){                          System.out.println("生成内容="+entry.getValue().getOutput());                  }          }

项目主页:http://www.open-open.com/lib/view/home/1359700183129