數據庫逆向生成代碼及Maven插件開發

        以前使用mybatis,能夠用mybatis generator逆向生成dao層代碼,詳見博客《數據庫逆向框架代碼生成工具:MyBatis Generator的使用》。公司使用的是本身開發的服務,因此最近抽空寫了一個逆向生成的工具,並作成了maven插件,之後就能夠很方便的實現dao層的相關代碼。java

        在開發以前已經想好了思路,經過velocity模板,實現代碼生成。上網搜了下velocity的代碼生成工具。搜到了《一個基於velocity模板引擎的代碼生成器》,下載了源碼進行了部署以及學習,做者的代碼寫的很是規範,基於jquery easyui和mybatis作了一個mybatis的封裝框架,而且考慮了多數據庫的支持,本身從中也收穫很多。另外也看了mybatis generator的源碼,由於裏面要兼容的東西多,因此代碼量也是很大的。mysql

        本身想作的比較簡單,只用基於公司現有的底層實現,逆向生成出來Dao層的代碼就能夠。不須要支持其餘數據庫,不須要提供UI界面,只用簡單的配置便可。因此實現的比較簡單,正由於簡單,修改起來也方便,學習成本也很低。下面進入正文。jquery


1實現方式

        1經過配置鏈接庫 2得到對應的表結構元數據 3進行相關類型轉換 4而後經過velocity模板生成對應的文件。git


須要注意:sql

        約定優於配置,命名必定要規範。好比數據庫的字段命名規範,多個單詞使用 _ 分割,這樣能夠方便轉換爲JavaBean的駝峯命名格式。數據庫的user_name,JavaBean中對應userName。  數據庫

         另外若是想支持本身的項目,須要修改velocity模板,若是有特殊需求,可能須要改下源碼。
apache

2實現過程

        首先須要經過讀取配置文件,鏈接數據庫,咱們可使用各類方式,好比最原生的jdbc,或者mybatis,這裏使用了Apache的DBCP以及DBUitls,另外配置文件使用properties,都是爲了實現起來簡單。mybatis


 配置文件配置有mysql的鏈接屬性,須要逆向生成的數據庫表名,生成的實體名,包名框架

       

2.把配置封裝在一個對象中,便於上下文使用(也是爲了maven插件使用,下文會說到)。maven

把數據庫的鏈接,以及查詢操做封裝在DBHelper中。

而後得到對應表的元數據,進行類型轉換,數據封裝爲velocity的模板數據,經過velocity生成代碼。


3.代碼細節

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目錄下


4封裝成Maven插件

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插件的方式,在其餘項目中引用運行



5源碼

源碼使用了別人的一些代碼進行了修改,類註釋中都有原做者

最後強調,代碼生成器不是萬能的,要根據本身的須要進行一些修改,代碼寫的比較簡單,見諒

源碼:《code-generator》

相關文章
相關標籤/搜索