代碼生成器原理

代碼生成器原理很簡單,用一句話歸納就是:將數據庫字段轉換成Java字段並輸出內容。前端

以下圖所示:java

輸入圖片說明

所以,首先須要作的是獲取表信息以及表的字段信息,通常有兩種方式,第一種:鏈接到數據庫,執行相關SQL,查詢出表結構信息。第二種:解析DDL,獲得相關信息,code-gen採用第一種作法。mysql

  • 獲取表信息

包括表名稱,表備註,Mysql能夠使用下面這個SQL。(code-gen源碼對應:com.gitee.gen.gen.mysql.MySqlTableSelector)git

SHOW TABLE STATUS FROM table_name

若是須要指定某張表,直接加where條件便可sql

SHOW TABLE STATUS FROM table_name where name = 'user_info';

查詢後結果以下:數據庫

Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
"user_info" "InnoDB" "10" "Dynamic" "0" "0" "16384" "0" "0" "0" "1" "2020-12-22 15:16:40" "utf8_general_ci" "用戶信息表"
  • 獲取表字段信息

Mysql能夠用以下SQL(code-gen對應源碼:com.gitee.gen.gen.mysql.MySqlColumnSelector):oracle

SHOW FULL COLUMNS FROM  user_info;

查詢後結果以下:sqlserver

Field Type Collation Null Key Default Extra Privileges Comment
"id" "int(11)" "NO" "PRI" "auto_increment" "select,insert,update,references" "自增主鍵"
"name" "int(11)" "NO" "select,insert,update,references" "姓名"
"create_time" "timestamp" "NO" "CURRENT_TIMESTAMP" "select,insert,update,references" "添加時間"

從表格中,能夠獲取字段名稱、類型、備註、是否主鍵、是否自增post

查詢出數據庫的基本信息後,把這信息放到對象中,方便後續處理。this

/**
 * 數據庫表定義,從這裏能夠獲取表名,字段信息
 */
public class TableDefinition {

    /**
     * 表名
     */
    private String tableName;

    /**
     * 表註釋
     */
    private String comment;

    /**
     * 字段
     */
    private List<ColumnDefinition> columnDefinitions

    ... 省略 getter  setter

}

其中TableDefinition類存放表信息,ColumnDefinition類存放字段信息

接下來是將TableDefinition對象中的變量綁定到Velocity模板當中去。

VelocityContext context = new VelocityContext();

TableDefinition tableDefinition = ...

context.put("table", tableDefinition);
context.put("columns", tableDefinition.getColumnDefinitions());


return VelocityUtil.generate(context, template);

VelocityContext存放Velocity變量,在對象中放入兩個變量table、columns,template是模板內容

而後再模板中就能夠使用對應的變量了,對應的模板能夠這麼寫:

/**
 * ${table.comment}
 */
public class ${context.javaBeanName} {

// Java字段信息
#foreach($column in $columns)
	/** ${column.comment} */
	private ${column.javaTypeBox} ${column.javaFieldName};
#end

// getter,setter部分
#foreach(${column} in ${columns})
	public void set${column.javaFieldNameUF}(${column.javaTypeBox} ${column.javaFieldName}) {
		this.${column.javaFieldName} = ${column.javaFieldName};
	}
	
	public ${column.javaTypeBox} get${column.javaFieldNameUF}() {
		return this.${column.javaFieldName};
	}
	
#end

}

獲得生成結果後,把內容返回到前端頁面。

處理多種數據庫

如何處理多種數據庫,這裏的關鍵點是要獲取數據庫的表結構以及字段信息,每種數據庫的獲取SQL是不同的,所以須要把獲取表信息和獲取字段信息抽象出來,而後讓實際的數據庫取實現抽象部分便可。

code-gen對應抽象類:

  • com.gitee.gen.gen.TableSelector 抽象類,用來獲取表信息 子類:

    • com.gitee.gen.gen.mysql.MySqlTableSelector
    • com.gitee.gen.gen.oracle.OracleTableSelector
    • com.gitee.gen.gen.postgresql.PostgreSqlTableSelector
    • com.gitee.gen.gen.sqlserver.SqlServerTableSelector
  • com.gitee.gen.gen.ColumnSelector 抽象類,用來獲取表字段信息 子類:

    • com.gitee.gen.gen.mysql.MySqlColumnSelector
    • com.gitee.gen.gen.oracle.OracleColumnSelector
    • com.gitee.gen.gen.postgresql.PostgreSqlColumnSelector
    • com.gitee.gen.gen.sqlserver.SqlServerColumnSelector
相關文章
相關標籤/搜索