以前使用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插件的方式,在其餘項目中引用運行
源碼使用了別人的一些代碼進行了修改,類註釋中都有原做者
最後強調,代碼生成器不是萬能的,要根據本身的須要進行一些修改,代碼寫的比較簡單,見諒