以前使用mybatis,能够用mybatis generator逆向生成dao层代码,详见博客《数据库逆向框架代码生成工具:MyBatis Generator的使用》。公司使用的是本身开发的服务,因此最近抽空写了一个逆向生成的工具,并作成了maven插件,之后就能够很方便的实现dao层的相关代码。java
在开发以前已经想好了思路,经过velocity模板,实现代码生成。上网搜了下velocity的代码生成工具。搜到了《一个基于velocity模板引擎的代码生成器》,下载了源码进行了部署以及学习,做者的代码写的很是规范,基于jquery easyui和mybatis作了一个mybatis的封装框架,而且考虑了多数据库的支持,本身从中也收获很多。另外也看了mybatis generator的源码,由于里面要兼容的东西多,因此代码量也是很大的。mysql
本身想作的比较简单,只用基于公司现有的底层实现,逆向生成出来Dao层的代码就能够。不须要支持其余数据库,不须要提供UI界面,只用简单的配置便可。因此实现的比较简单,正由于简单,修改起来也方便,学习成本也很低。下面进入正文。jquery
1经过配置链接库 2得到对应的表结构元数据 3进行相关类型转换 4而后经过velocity模板生成对应的文件。git
须要注意:sql
约定优于配置,命名必定要规范。好比数据库的字段命名规范,多个单词使用 _ 分割,这样能够方便转换为JavaBean的驼峰命名格式。数据库的user_name,JavaBean中对应userName。 数据库
另外若是想支持本身的项目,须要修改velocity模板,若是有特殊需求,可能须要改下源码。
apache
首先须要经过读取配置文件,链接数据库,咱们可使用各类方式,好比最原生的jdbc,或者mybatis,这里使用了Apache的DBCP以及DBUitls,另外配置文件使用properties,都是为了实现起来简单。mybatis
配置文件配置有mysql的链接属性,须要逆向生成的数据库表名,生成的实体名,包名框架
2.把配置封装在一个对象中,便于上下文使用(也是为了maven插件使用,下文会说到)。maven
把数据库的链接,以及查询操做封装在DBHelper中。
而后得到对应表的元数据,进行类型转换,数据封装为velocity的模板数据,经过velocity生成代码。
DBHelper中,经过配置初始化datasource,而后建立DBUtil的QueryRunner查询器。
经过QueryRunner的query方法,查询数据,这里用到MapListHandler解析器,能够把查询结果转换成List<Map<String, Object>>
接下来把查询到的元数据,转换为自定义对象,把数据库类型转换为java类型。这里有一个技术细节,DBUtils返回的Map对象里面的key是不区分大小写的。
生成代码,对应的velocity模板中的属性
而后就是渲染到模板了,须要什么属性,能够本身封装,模板也能够根据本身须要进行修改,这里是公司实体对应的模板
package ${package}.contract.entity; import com.bj58.sfft.utility.dao.annotation.Column; import com.bj58.sfft.utility.dao.annotation.Id; import com.bj58.sfft.utility.dao.annotation.NotDBColumn; import com.bj58.sfft.utility.dao.annotation.Table; import com.bj58.spat.scf.serializer.component.annotation.SCFMember; import com.bj58.spat.scf.serializer.component.annotation.SCFSerializable; #set($hasDate=0) #foreach($column in $columns) #if($column.javaType=='Date' && $hasDate==0) import java.util.Date; #set($hasDate=1) #end #end @Table(name="${table}") @SCFSerializable public class ${entity}{ @NotDBColumn private static final long serialVersionUID = 1L; #foreach($column in $columns) @SCFMember #if(${column.isPk}) #if(!${column.isIdentityPk}) @Id(insertable=true) #end #else @Column(name="${column.columnName}") #end private ${column.javaType} ${column.javaFieldName}; #end #foreach(${column} in ${columns}) public void set${column.javaFieldNameUF}(${column.javaType} ${column.javaFieldName}){ this.${column.javaFieldName} = ${column.javaFieldName}; } public ${column.javaType} get${column.javaFieldNameUF}(){ return this.${column.javaFieldName}; } #end}
这里须要生成整个Dao层代码,因此把方法写成了回调的形式
最后运行代码,会把代码生成在 项目的target/generator目录下
maven插件开发,也是本身第一次弄,官方文档Maven Plugin
上网搜了下maven插件开发,《开发本身的Maven插件之一:hello world》
实现过程也很简单,在pom中添加插件依赖,在代码中继承AbstractMojo类 ,实现execute方法
使用Intellij IDEA的话,能够选择maven模板
经过引用插件,就能够在项目中运行code-generator:generator命令,或者点击右侧插件运行
须要注意资源文件的加载方式
运行maven插件,项目是能够不编译的,所以要经过maven注入的basedir,得到项目的路径
若是在Java中运行,首先是须要编译项目的,经过java得到文件路径是在类编译的根目录下的
为了便于使用和测试,因此源码中,能够调用main包下的CodeGenerator类。
也能够把项目install本地,经过maven插件的方式,在其余项目中引用运行
源码使用了别人的一些代码进行了修改,类注释中都有原做者
最后强调,代码生成器不是万能的,要根据本身的须要进行一些修改,代码写的比较简单,见谅