autoCode代码生成器

autoCode是一个代码生成器项目,基于velocity模板引擎,采用SpringMVC + mybatis + jquery easyUI.

其特点主要有:

  • 用户登陆 - 每个用户有他自己独立的数据库连接配置和模板配置
  • 数据源配置 - 可以配置多个数据源,多种数据库类型(目前支持Mysql,MSServer数据库,可以扩展)
  • 模板配置 - 定义自己的模板,采用velocity模板语法.这样可以根据模板来生成不同的代码,如POJO,Dao,mybatis配置文件等
  • 操作简单 - 生成代码只需三步:1. 选择数据源;2. 选择表;3. 选择模板.

页面截图:

首页

 

配置数据源

 

配置模板

修改模板:

生成代码第一步:

生成代码第二步:

生成代码第三步:

生成结果,点击左边的树菜单可以查看内容:

 

 

下载地址:http://pan.baidu.com/share/link?shareid=3882948706&uk=4114964897 

 

1. 解压压缩包,eclipse正常导入工程(import... -> Existing Projects into Workspace..)

2. 导入数据库(MYSQL),SQL文件在项目根目录下,名为autoCode.sql,运行里面的内容即可

3. 修改数据库连接参数,配置文件在src/main/resources/server.properties

4. 启动项目

登录用户名密码均为admin

 

首次使用

第一步添加数据源:

输入数据库连接参数

保存后测试连接

第二步:生成代码

选择一个数据源

选择一张表,这里为了演示,我们用代码生成器自带的用户表

选择模板,这里系统自带了几个模板

生成后,点击树状菜单查看模板内容

 

大家也可以自行创建自己的模板,模板参数在界面右边已经给出

也可以仿照现有的模板自己琢磨下 O(∩_∩)O

这里还提供了用户管理,可以开几个账号给其他小伙伴使用,各自使用自己的数据源,互不干扰.



autoCode代码生成系统设计思路



先来看下一个普通的pojo类由哪几部分组成

  • 类名(表名)
  • 属性名(字段名)
  • 属性类型(字段类型)

因此,只要我们想办法获取到表结构的一些信息,然后把这些信息拼装成对应的java类信息即可.

就Mysql数据库来说,获取一个数据库中的表名的SQL是:SHOW TABLES

如图所示,这里我查询了autoCode自己的数据库

数据库表名获取到了,接着我们应该获取一张表里面的所有字段信息,mysql对应的SQL是:DESC 表名

如图所示,我们查询了datasource_config表的信息.其中字段名,字段类型,主键,自增都可以得到

我们只要把这些信息放在对应的java类里面就可以使用了.系统对应的是ColumnDefinition类

一个类代表一个字段的信息,因此所有字段的信息我们应该用List<ColumnDefinition>来保存

 

我们得到了表名以及字段信息,现在要做的是把这些信息放到velocity上下文中去

然后通过模板来来生成代码

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. private String doGenerator(SQLContext sqlContext,String template){  
  2.         VelocityContext context = new VelocityContext();  
  3.           
  4.         context.put("context", sqlContext);  
  5.         context.put("table", sqlContext.getTableDefinition());  
  6.         context.put("pkColumn", sqlContext.getTableDefinition().getPkColumn());  
  7.         context.put("columns", sqlContext.getTableDefinition().getColumnDefinitions());  
  8.           
  9.         return VelocityUtil.generate(context, template);  
  10.     }  

这里是GeneratorService类中的一个方法,SQLContext中存放了表名,字段信息

然后安装事先约定好的velocity语法生成内容.String template是模板内容

代码生成完后直接返回到前台页面即可



autoCode类设计


由于代码生成系统需要支持多种数据库,因此在类的设计上需要仔细得思考下,把相同的部分抽取出来,不同的部分通过接口或抽象类来扩展.

先来看下不同的地方

  1. 获取数据库中所有的表
  2. 获取表中的字段信息

再来看相同的地方:

  1. 返回表名集合
  2. 返回SQL上下文集合(SQL上下文中已经封装好了表名,字段等信息)

 

针对于相同点和不同点,我分别用了两个抽象来来实现

如果所示,getShowTablesSQL()返回的是查询所有表名的SQL,getTableDetailSQL()返回具体表信息的SQL,buildColumnDefinition()是构建字段信息.这三个方法需要子类去实现.

 

getTableList()是抽象类中已经实现好的方法,用来返回表名集合

同样buildSQLContextList()也是抽象类中实现好的方法,用来构建SQL上下文,SQL上下文中已经封装好了表名,字段等信息

我们需要用到的也只有这两个方法而已

 

以后要添加其它数据库类型,只需要继承者两个类即可

下面贴上用户操作序列图

 

最后贴上系统生成代码的序列图

 

  1. 用户请求到Controller类
  2. Controller类调用Service中的generate()方法
  3. Service通过工厂类构建出对应的数据库类型SQLService,这个SQLService决定了使用哪种数据库
  4. 接着SQLService获取TableSelector
  5. TableSelector通过表名构建SQLContext上下文
  6. 遍历SQLContext上下文,通过velocity模板生成代码内容



autoCode代码生成器,velocity变量详解


autoCode提供了一组velocity变量,这些变量包含了数据库表,字段,java类字段信息

运用这些变量我们就能构建出一个自己需要的模板文件

首先来看下变量列表:

前面是变量名,后面是对变量的说明

 

接下来我们就用这些变量来编写一个模板

这里有一张后台用户表back_user,它有三个字段,如图

现在我们要根据这张表生成一个Entity,那模板内容如下:

假设包名为test

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package ${context.packageName}.entity;  
  2.   
  3. public class ${context.javaBeanName} {  
  4. #foreach($column in $columns)   
  5.     private ${column.javaType} ${column.javaFieldName};  
  6. #end  
  7.   
  8. #foreach(${column} in ${columns})   
  9.     public void set${column.javaFieldNameUF}(${column.javaType} ${column.javaFieldName}){  
  10.         this.${column.javaFieldName} = ${column.javaFieldName};  
  11.     }  
  12.   
  13.     public ${column.javaType} get${column.javaFieldNameUF}(){  
  14.         return this.${column.javaFieldName};  
  15.     }  
  16.   
  17. #end  
  18. }  


使用代码生成器生成后的代码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package test.entity;  
  2.   
  3. public class BackUser {  
  4.     private String username;  
  5.     private String password;  
  6.     private Date addTime;  
  7.   
  8.     public void setUsername(String username){  
  9.         this.username = username;  
  10.     }  
  11.   
  12.     public String getUsername(){  
  13.         return this.username;  
  14.     }  
  15.   
  16.     public void setPassword(String password){  
  17.         this.password = password;  
  18.     }  
  19.   
  20.     public String getPassword(){  
  21.         return this.password;  
  22.     }  
  23.   
  24.     public void setAddTime(Date addTime){  
  25.         this.addTime = addTime;  
  26.     }  
  27.   
  28.     public Date getAddTime(){  
  29.         return this.addTime;  
  30.     }  
  31.   
  32. }  

 

接下来我们编写一个复杂的例子,编写一个mybatis的配置文件模板

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE  mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >  
  3. <mapper namespace="${context.packageName}.dao.${context.javaBeanName}Dao">  
  4.     <resultMap id="queryResultMap" type="${context.packageName}.entity.${context.javaBeanName}">  
  5.         #foreach($column in $columns)  
  6.         <result column="${column.columnName}" property="${column.javaFieldName}" jdbcType="${column.mybatisJdbcType}" />  
  7.         #end  
  8.     </resultMap>  
  9.   
  10.     <select id="find" parameterType="${context.packageName}.entity.${context.javaBeanName}"  
  11.         resultMap="queryResultMap">  
  12.         SELECT *  
  13.         FROM ${table.tableName} t        
  14.         WHERE 1=1  
  15.         #foreach($column in $columns)  
  16.     <if test="${column.javaFieldName}!=null">  
  17.         AND ${column.columnName} = #{${column.javaFieldName},jdbcType=${column.mybatisJdbcType}}  
  18.     </if>  
  19.         #end  
  20.         ORDER BY ${context.javaPkName} desc  
  21.   
  22.     </select>  
  23.   
  24.   
  25.     <insert id="save" parameterType="${context.packageName}.entity.${context.javaBeanName}"  
  26. #if(${pkColumn.isIdentity})  
  27.     keyProperty="${context.javaPkName}" keyColumn="${context.pkName}" useGeneratedKeys="true"  
  28. #end  
  29.     >  
  30.     INSERT INTO ${table.tableName}  
  31.          (  
  32.  #set ($i=0)   
  33.         #foreach($column in $columns)   
  34.             #if(!${column.isIdentityPk})                 
  35.         #if($i > 0),#end ${column.columnName}  
  36.                #set($i=$i+1)  
  37.             #end            
  38.         #end  
  39.           )  
  40.     VALUES (  
  41.         #set ($i=0)   
  42.         #foreach($column in $columns)   
  43.             #if(!${column.isIdentityPk})                 
  44.         #if($i > 0),#end #{${column.javaFieldName},jdbcType=${column.mybatisJdbcType}}  
  45.                #set($i=$i+1)  
  46.             #end            
  47.         #end  
  48.    
  49.         )  
  50.     </insert>  
  51.   
  52.   
  53.     <update id="update" parameterType="${context.packageName}.entity.${context.javaBeanName}">  
  54.     UPDATE ${table.tableName}  
  55.     SET   
  56. #set ($i=0)   
  57.         #foreach($column in $columns)   
  58.             #if(!${column.isPk})                 
  59.         #if($i > 0),#end ${column.columnName}=#{${column.javaFieldName},jdbcType=${column.mybatisJdbcType}}  
  60.                #set($i=$i+1)  
  61.             #end            
  62.         #end      
  63.     WHERE ${context.pkName} = #{${context.javaPkName},jdbcType=${context.mybatisPkType}}  
  64.     </update>  
  65.   
  66.     <select id="get" resultMap="queryResultMap" parameterType="java.io.Serializable">  
  67.         SELECT *  
  68.         FROM ${table.tableName}  
  69.         WHERE ${context.pkName} = #{${context.javaPkName},jdbcType=${context.mybatisPkType}}  
  70.     </select>  
  71.       
  72.     <delete id="del" parameterType="${context.packageName}.entity.${context.javaBeanName}">  
  73.         DELETE FROM ${table.tableName}  
  74.         WHERE ${context.pkName} = #{${context.javaPkName},jdbcType=${context.mybatisPkType}}  
  75.     </delete>  
  76.   
  77. </mapper>  


生成后的代码:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE  mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >  
  3. <mapper namespace="test.dao.BackUserDao">  
  4.     <resultMap id="queryResultMap" type="test.entity.BackUser">  
  5.         <result column="username" property="username" jdbcType="VARCHAR" />  
  6.         <result column="password" property="password" jdbcType="VARCHAR" />  
  7.         <result column="add_time" property="addTime" jdbcType="TIMESTAMP" />  
  8.     </resultMap>  
  9.   
  10.     <select id="find" parameterType="test.entity.BackUser"  
  11.         resultMap="queryResultMap">  
  12.         SELECT *  
  13.         FROM back_user t  
  14.         WHERE 1=1  
  15.         <if test="username!=null">  
  16.             AND username = #{username,jdbcType=VARCHAR}  
  17.         </if>  
  18.         <if test="password!=null">  
  19.             AND password = #{password,jdbcType=VARCHAR}  
  20.         </if>  
  21.         <if test="addTime!=null">  
  22.             AND add_time = #{addTime,jdbcType=TIMESTAMP}  
  23.         </if>  
  24.         ORDER BY username desc  
  25.   
  26.     </select>  
  27.   
  28.   
  29.     <insert id="save" parameterType="test.entity.BackUser">  
  30.         INSERT INTO back_user  
  31.         (  
  32.         username  
  33.         , password  
  34.         , add_time  
  35.         )  
  36.         VALUES (  
  37.         #{username,jdbcType=VARCHAR}  
  38.         , #{password,jdbcType=VARCHAR}  
  39.         , #{addTime,jdbcType=TIMESTAMP}  
  40.   
  41.         )  
  42.     </insert>  
  43.   
  44.   
  45.     <update id="update" parameterType="test.entity.BackUser">  
  46.         UPDATE back_user  
  47.         SET  
  48.         password=#{password,jdbcType=VARCHAR}  
  49.         , add_time=#{addTime,jdbcType=TIMESTAMP}  
  50.         WHERE username = #{username,jdbcType=VARCHAR}  
  51.     </update>  
  52.   
  53.     <select id="get" resultMap="queryResultMap" parameterType="java.io.Serializable">  
  54.         SELECT *  
  55.         FROM back_user  
  56.         WHERE username = #{username,jdbcType=VARCHAR}  
  57.     </select>  
  58.   
  59.     <delete id="del" parameterType="test.entity.BackUser">  
  60.         DELETE FROM back_user  
  61.         WHERE username = #{username,jdbcType=VARCHAR}  
  62.     </delete>  
  63.   
  64. </mapper>  

我们取一个update语句来分析:


<update id="update" parameterType="${context.packageName}.entity.${context.javaBeanName}">
    UPDATE ${table.tableName} // 表名
    SET 
        #set ($i=0) // 定义一个变量$i=0
        #foreach($column in $columns) // 循环列
            #if(!${column.isPk}) // 如果不是主键,因为主键是不能被修改的               
        #if($i > 0),#end // 这里添加逗号,从第二个开始就开始加逗号

               ${column.columnName}=#{${column.javaFieldName},jdbcType=${column.mybatisJdbcType}} // 修改字段
               #set($i=$i+1) // 每次循环后变量加1
            #end          
        #end    
    WHERE ${context.pkName} = #{${context.javaPkName},jdbcType=${context.mybatisPkType}} // 主键=#{java主键}
</update>

 

由此可以看出这套velocity语法可以满足大部分要求,当然特殊的地方还是需要自己去修改.毕竟代码生成器也不是外能的


自动代码生成器Autocode)是一种可以帮助开发人员快速生成代码的工具。它基于一系列的规则和模板,根据用户定义的条件和需求,自动地生成所需的代码。 自动代码生成器可以应用于各种编程语言和开发环境,如Java、Python、C#等。它通过识别用户的输入和需求,自动分析并生成相应的代码结构、语法和逻辑。这样,开发人员就可以减少繁琐的手动编写代码的重复劳动,从而提高开发效率和质量。 使用自动代码生成器,首先需要定义好生成的代码的规则和模板。这些规则和模板包括了各种条件判断、循环结构、函数定义等。然后,开发人员根据需要输入具体的数据或设置特定的条件。自动代码生成器会根据这些输入自动生成符合要求的代码。 通过使用自动代码生成器,开发人员可以节省大量的时间和精力。它可以帮助快速生成常用或重复的代码片段,减轻了人工编码的工作量,降低了出错的概率。同时,它还提供了可定制化的功能,可以根据具体的项目需求进行开发。 然而,自动代码生成器并非完全自动化解决方案。尽管它可以生成大部分的代码,但对于某些复杂或具有特殊逻辑的代码,仍然需要开发人员手动编写。此外,自动生成的代码可能需要进行进一步的修改和调整,以适应具体开发环境和需求。 总而言之,自动代码生成器是一种能够帮助开发人员快速生成代码的工具。它可以提高开发效率和质量,减少开发工作量。然而,在使用自动代码生成器时,仍然需要开发人员具备一定的编程知识和技能,以便在生成的代码基础上进行进一步的修改和调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值