背景
本來code-builder
是專門為MyBatis Enhance
來編寫的一塊程式碼生成器,不過僅僅使用到Enhance
卻沒有什麼新鮮感,所以把生成這塊分離出來提供給大家使用,希望可以對提高專案研發效率提供一些幫助。
code-builder可以用來做什麼?
code-builder
是一款程式碼生成maven mojo
外掛,通過簡單的配置就可以完成資料庫內Table
轉換Entity
或者其他實體類,想怎麼生成完全根據你的個人業務邏輯,code-builder
儘可能的完善的提供資料庫內的一些定義的資訊,讓你更方便更靈活的來生成Java
檔案。
歡迎關注公眾號
關注微信公眾號,回覆加群
,獲取交流群群號。
原始碼地址
- 碼雲地址:gitee.com/hengboy/cod…
- GitHub地址:github.com/hengyuboy/c…
歡迎去碼雲進行Issue、喜歡的給我來個Star吧
使用環境
Maven
構建的專案JDK 1.6
以上版本
實現方式
是怎麼獲取到的資料庫資訊?
code-builder
內部採用了java.sql.Connection
的MetaData
後設資料的方式來獲取資料庫內Table
、Column
等資訊,MetaData
是不侷限於任何的資料庫型別的,所以code-builder
在基礎設計上是可以在任何資料庫型別中來完成它的生成任務的,不過初版本僅支援了MySQL
、MariaDB
這兩種資料庫型別,在code-builder
後期更新版本中會把主流的資料庫進行新增。
生成模板選型
目前code-builder
內部採用了freemarker
模板來完成實體類的自動生成,模板由使用者來自定義編寫,內部預留了使用其他模板的方式,如果你需要使用別的模板,如:Velocity
,對應新增生成的實現業務邏輯即可。
怎麼配置?
SpringBoot 方式配置
在1.0.3.RELEASE
版本新增了整合SpringBoot
的starter
,依賴如下所示:
- 使用
Maven
構建工具時,複製下面的內容到pom.xml
配置檔案內
<dependency>
<groupId>com.gitee.hengboy</groupId>
<artifactId>code-builder-spring-boot-starter</artifactId>
<version>1.0.3.RELEASE</version>
</dependency>
複製程式碼
- 如果你是用的
Gradle
構建工具,那麼複製下面的內容到你的build.gradle
compile group: 'com.gitee.hengboy', name: 'code-builder-spring-boot-starter', version: '1.0.3.RELEASE'
複製程式碼
那麼我們在application.yml
或者application.properties
配置檔案內該怎麼配置相關的引數呢?
hengboy:
code:
builder:
execute: true
configuration:
package-prefix: com.code.builder.sample.codebuildersample
templates:
-
name: entity.ftl
packageName: model
fileSuffix: Entity
-
name: service.ftl
packageName: service
fileSuffix: Service
-
name: controller.ftl
packageName: controller
fileSuffix: Controller
generator-by-pattern: '%app_user_info%'
db-type: mysql
engine-type-enum: freemarker
builder-dir: classes.templates.builder
target-dir: generated-sources.java
tables:
- app_shop_type
- app_user_exchange_good
ignore-class-prefix: App
複製程式碼
每個引數的具體介紹請往下看。
Maven Plugin 方式配置
由於code-builder
是Maven mojo
外掛的形式建立的,所以我們只需要在專案的pom.xml
檔案內新增plugin
外掛配置,如下所示:
<plugin>
<groupId>com.gitee.hengboy</groupId>
<artifactId>code-builder-maven-plugin</artifactId>
<version>1.0.3.RELEASE</version>
<executions>
<execution>
<goals>
<goal>generator</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
</dependencies>
<configuration>
<execute>true</execute>
<dbType>MySQL</dbType>
<dbDriverClassName>com.mysql.jdbc.Driver</dbDriverClassName>
<dbName>xxxx</dbName>
<dbUserName>xxxx</dbUserName>
<dbPassword>xxxxx</dbPassword>
<dbUrl>jdbc:mysql://xxx.xx.xx.xx:3306</dbUrl>
<tables>
<table>app_shop_type</table>
<table>app_user_exchange_good</table>
</tables>
<engineType>FREEMARKER</engineType>
<generatorByPattern>%app_user_info%</generatorByPattern>
<ignoreClassPrefix>App</ignoreClassPrefix>
<builderDir>classes.templates.builder</builderDir>
<builder>
<packagePrefix>com.code.builder.sample</packagePrefix>
<templates>
<template>
<name>entity.ftl</name>
<packageName>model</packageName>
</template>
<template>
<name>service.ftl</name>
<packageName>service</packageName>
<fileSuffix>Service</fileSuffix>
</template>
<template>
<name>mapper.ftl</name>
<packageName>mapper</packageName>
<fileSuffix>Mapper</fileSuffix>
</template>
</templates>
</builder>
</configuration>
</plugin>
複製程式碼
資料庫驅動依賴新增
code-builder
不侷限你使用的資料庫型別,所以在生成時需要使用者新增對應資料型別的依賴,如上面的配置中則是新增了MySQL
資料庫的依賴
.....
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
</dependencies>
.....
複製程式碼
僅僅在使用
Maven-Plugin
形式新增資料驅動依賴
生成的控制開關
並不是每一次的編譯
或者打包
時都需要生成對應的實體,針對這種情況code-builder
新增了execute
引數來控制開啟與關閉。
true
:開啟自動生成false
:關閉自動生成
資料庫型別配置
執行自動生成前需要配置資料庫的相關配置資訊
dbType
:資料庫型別,預設使用MySQL
資料庫型別。dbDriverClassName
:資料庫驅動類名,根據不用的資料庫型別配置不同的驅動類名,預設根據dbType
使用內部定義的類名,如需自定義可以設定。(僅maven-plugin使用)
資料庫基本資訊配置 (僅maven-plugin使用)
dbName
:資料庫名稱dbUserName
:資料庫使用者名稱dbPassword
:資料庫密碼dbUrl
:資料庫連線路徑,連線路徑不需要填寫資料庫名,正確示例如:jdbc:mysql://localhost:3306
生成表名符合規則的表
根據表示式來建立表,表示式與模糊查詢語句表示式一般無二,配置generatorByPattern
引數並設定對應的表示式就可以根據表示式來匹配出參與生成的Table
列表。
- 指定字首匹配
<generatorByPattern>app_order%</generatorByPattern>
複製程式碼
示例:將會匹配出app_order_info
、app_order_record
等表。
- 指定字尾匹配
<generatorByPattern>%order</generatorByPattern>
複製程式碼
示例:將會匹配出app_good_order
、app_exchange_order
等表。
- 包含匹配
<generatorByPattern>%order%</generatorByPattern>
複製程式碼
示例:將會匹配出app_order_info
、app_good_order
等表。
生成指定表
code-builder
支援指定單個或者多個表來生成,只需要配置tables
引數即可,如下所示:
<tables>
<table>app_shop_type</table>
<table>app_user_exchange_good</table>
</tables>
複製程式碼
上面的配置是本次生成僅操作app_shop_type
、app_user_exchange_good
兩張表。
注意:
tables
引數的優先順序要高於generatorByPattern
引數。
自定義builder所需模板路徑
code-builder
會自動去找classes/templates/builder
下的模板,如果使用預設的freemarker
模板來生成,那麼模板所存放的位置為classes/templates/builder/freemarker
。
如果你想自定義模板的路徑可以設定builderDir
的地址,在這裡因為考慮到了不同作業系統的分隔符不一樣(Windows
系統分隔符\
,Linux
以及O SX
分隔符為/
)所以這裡採用.
分隔符配置,code-builder
會自動根據作業系統來轉換路徑,配置如下所示:
<builderDir>classes.code.builder</builderDir>
複製程式碼
注意:
freemarker
資料夾不允許修改,只能修改code-builder
載入模板的根路徑。
排除生成實體後的字首
資料庫設計有時需要新增字首,如:app_
、sys_
等,實際生成實體後字首則是並不想展示,那麼配置引數ignoreClassPrefix
就可以自動排除字首,如下所示:
<ignoreClassPrefix>App</ignoreClassPrefix>
複製程式碼
注意:由於替換生成後的類名稱所以這裡要準守駝峰命名規則首字母大寫,一次只能配置一個替換字首。
使用前AppUserInfoEntity
,使用後UserInfoEntity
。
模板配置
使用templates
標籤配置自定義的模板列表,一次可以使用單個或者多個模板進行生成,如下配置:
<templates>
<template>
<name>entity.ftl</name>
<packageName>entity</packageName>
<fileSuffix>entity</fileSuffix>
</template>
<template>
<name>service.ftl</name>
<packageName>service</packageName>
<fileSuffix>Service</fileSuffix>
</template>
<template>
<name>mapper.ftl</name>
<packageName>mapper</packageName>
<fileSuffix>Mapper</fileSuffix>
</template>
</templates>
複製程式碼
name
:freemarker
目錄下模板的名稱,必填
packageName
:生成該模板檔案後的子包名稱,非必填
fileSuffix
:生成檔案的字尾,如:配置字尾為Entity
,則新增字尾後的檔名為UserInfoEntity
,字尾首字母會自動根據駝峰轉換成大寫
內建引數
模板驅動資料模型內建了部分引數,code-builder
準備的每一個引數都是在生成實體類時都可能會用到的。
Table引數
tableName
表名
,資料型別:java.lang.String
remark
表備註資訊
,資料型別:java.lang.String
entityName
實體類名稱
,如:user_info
轉換為userInfo
,資料型別:java.lang.String
columns
列列表
,資料型別:java.util.List<Column>
primaryKeys
主鍵列表
,資料型別:java.util.List<Column>
hasSqlDate
是否存在java.sql.Date
型別,true
:存在,false
:不存在,資料型別:java.lang.Boolean
hasTimeStamp
是否存在java.sql.TimeStamp
型別,true
:存在,false
:不存在,資料型別:java.lang.Boolean
hasBigDecimal
是否存在java.math.BigDecimal
型別,true
:存在,false
:不存在,資料型別:java.lang.Boolean
使用方式
freemarker模板
:${table.xxx}
,如表名的使用為${table.tableName}
Column引數
columnName
列名
,如:user_id
,資料型別:java.lang.String
primaryKey
是否為主鍵
,資料型別:java.lang.Boolean
,true
:主鍵,false
:非主鍵foreignKey
是否為外來鍵
,資料型別:java.lang.Boolean
,true
:外來鍵,false
:非外來鍵size
列長度
,資料型別:java.lang.Integer
decimalDigits
小數點精度
,資料型別:java.lang.Integer
nullable
列是否為空
,資料型別:java.lang.Boolean
,true
:為空,false
:非空autoincrement
是否自增
,資料型別:java.lang.Boolean
,true
:自增列,false
:普通列defaultValue
預設值
,資料型別:java.lang.String
remark
列備註
,資料型別:java.lang.String
jdbcType
JDBC型別
,對應java.sql.Types
內型別,資料型別:java.lang.Integer
jdbcTypeName
JDBC型別名稱
,資料型別:java.lang.String
javaProperty
格式化後的屬性名稱
,如:userId
,資料型別:java.lang.String
javaType
Java資料型別短名
,如:TimeStamp
,資料型別:java.lang.String
fullJavaType
Java資料型別全名
,如:java.sql.TimeStamp
,資料型別:java.lang.String
使用方式
freemarker模板
:${column.xxx}
,如列名的使用為${column.columnName}
基礎引數
className
:Class名稱,freemarker指定模板生成檔案的類名,模板內配置${className}
使用packageName
:Package名稱,freemarker指定模板生成檔案的包名,模板內配置${packageName}
使用
怎麼自定義模板?
下面提供一個簡單的模板示例,根據上面的內建引數
可以任意自定義生成檔案的內容。
<#if (packageName)??>
package ${packageName};
</#if>
import lombok.Data;
<#if (table.hasSqlDate)>
import java.sql.Date;
</#if>
<#if (table.hasTimeStamp)>
import java.sql.Timestamp;
</#if>
<#if (table.hasBigDecimal)>
import java.math.BigDecimal;
</#if>
/**
* <p>本類程式碼由code-builder自動生成</p>
* <p>表名: ${table.tableName} - ${table.remark}</p>
* ===============================
* Created with code-builder.
* User:恆宇少年
* Date:${.now}
* 簡書:http://www.jianshTu.com/u/092df3f77bca
* 碼雲:https://gitee.com/hengboy
* ================================
*/
@Data
public class ${className} {
<#list table.primaryKeys as key>
/**
* ${key.columnName} - ${key.remark}
*/
private ${key.javaType} ${key.javaProperty};
</#list>
<#list table.columns as column>
<#if (!column.primaryKey)>
/**
* ${column.columnName} - ${column.remark}
*/
private ${column.javaType} ${column.javaProperty};
</#if>
</#list>
}
複製程式碼
上面是一個資料實體的freemarker
模板內容,把這個模板存放到freemarker
目錄下,對應在templates
標籤內新增配置就可以完成資料實體的自動建立,建立後的資料實體內容如下所示:
package com.code.builder.sample.model;
import lombok.Data;
import java.sql.Timestamp;
/**
* <p>本類程式碼由code-builder自動生成</p>
* <p>表名: app_balance_type - 餘額型別資訊表</p>
* ===============================
* Created with code-builder.
* User:恆宇少年
* Date:Jul 17, 2018 9:09:13 PM
* 簡書:http://www.jianshTu.com/u/092df3f77bca
* 碼雲:https://gitee.com/hengboy
* ================================
*/
@Data
public class BalanceTypeEntity {
/**
* BT_ID - 餘額型別主鍵
*/
private String btId;
/**
* BT_NAME - 餘額型別名稱
*/
private String btName;
/**
* BT_FLAG - 餘額型別標識
*/
private String btFlag;
/**
* BT_CREATE_TIME - 新增時間
*/
private Timestamp btCreateTime;
/**
* BT_MARK - 餘額型別備註資訊
*/
private String btMark;
}
複製程式碼
建立的實體類去了哪裡?
建立的實體類會在target/generated-sources/java
目錄下,如果你配置packagePrefix
引數,會自動在生成目錄下建立packagePrefix
配置值的子目錄。
如:
<packagePrefix>com.code.builder.sample</packagePrefix>
複製程式碼
則最終建立的生成根目錄為:target/generated-sources/java/com/code/builder/sample
怎麼使用?
SpringBoot 方式使用
執行專案
就可以根據配置生成對應的檔案
Maven Plugin 方式使用
- 執行
mvn clean
命令用於清空target
目錄下的內容 - 執行
mvn compile
命令編譯專案並且生成實體類
為什麼SpringBoot方式不用配置資料庫資訊?
Maven Plugin
方式是通過配置的資料庫連線資訊
以及資料庫連線驅動獲取資料庫連線物件Connection
後來操作JDBC後設資料
。
而SpringBoot
方式則是直接使用專案中配置的DataSource
物件例項來進行獲取的Connection
資料庫連線物件後來操作JDBC後設資料
。
注意:如果你是多資料來源專案,預設會使用
primary
資料來源例項。