項(xiàng)目地址:https://github.com/uncleAndyChen/mybatis-generator/tree/master/mybatis-generator-enhance
運(yùn)行本工程生成表配置內(nèi)容,一定要連接參數(shù)lower_case_table_names配置為0或者2的數(shù)據(jù)庫服務(wù)器,并且是配置為0或者2之后才創(chuàng)建的數(shù)據(jù)表,否則,生成的表配置內(nèi)容的表名,全是小寫的,并非駝峰式命名法。表配置內(nèi)容生成好之后,重新生成 mapper 時(shí)連接的數(shù)據(jù)庫服務(wù)器的lower_case_table_names配置值,對生成結(jié)果沒有影響。
本文對應(yīng)的完整項(xiàng)目
- github: https://github.com/uncleAndyChen/mybatis-generator
- gitee: https://gitee.com/uncleAndyChen/mybatis-generator
進(jìn)入以上項(xiàng)目路徑可查看更詳細(xì)的介紹。
本擴(kuò)展的作用
2019-06-19 更新
- 生成的*Mapper.xml文件中的腳本,表名取MBG所需配置文件中配置的值(工程中的配置文件是:generatorConfig.xml),而不是從數(shù)據(jù)庫讀取到的值。
- 如果數(shù)據(jù)庫表名采用下劃線命名法,請忽略這個(gè)作用。
- 數(shù)據(jù)庫表名、字段名命名法:
-
之前本人推薦采用駝峰命名法。
- 想要保持統(tǒng)一的命名規(guī)則。
- 不知道通過配置的方式兼顧兩種命名法,即數(shù)據(jù)庫表名、字段名在采用下劃線命名法的情況下,通過 MBG 生成的對應(yīng)每一個(gè)表的 POJO 采用駝峰命名法,查詢數(shù)據(jù)時(shí)不需要考慮 MBG 生成的 xml 映射文件中的
resultMap,如 parent_id 與 parentId 的映射。
-
現(xiàn)在推薦下劃線命名法。
- 這是為了避免因 windows 與 linux 以及云數(shù)據(jù)庫的大小寫敏感不一致,從而帶來不必要的麻煩。
- 同時(shí)也是考慮到絕大多數(shù)同行的習(xí)慣。
- 最主要的,是解決了之前不知道的兼顧兩種命名法的辦法(好象有一點(diǎn)拗口~~)
-
之前本人推薦采用駝峰命名法。
- 給表名添加MySQL“邊界”,用 `(左上角數(shù)字鍵1左邊、Tab鍵上邊、Esc鍵下邊的鍵)引起來。目的是分表時(shí)進(jìn)行表名替換,把每張個(gè)表的表名當(dāng)作一個(gè)整體,避免表名補(bǔ)充部分替換。
解決兩個(gè)問題
- 適應(yīng)lower_case_table_names的三種配置值。
- 利用MyBatis插件,根據(jù)業(yè)務(wù)規(guī)則,對表名進(jìn)行動(dòng)態(tài)替換。
自己擴(kuò)展的好處
- 比起直接修改MBG源代碼,這種方式對MBG無代碼侵入,方便將來升級MBG。
- 符合面向?qū)ο笤O(shè)計(jì)的【開閉原則】,即通過增加代碼來為軟件添加新功能,而不是直接修改原有代碼。這一點(diǎn),MBG做得非常好,除了可以非常方便的擴(kuò)展之外,還可以寫各種插件以實(shí)現(xiàn)自己的業(yè)務(wù)需要。
自己擴(kuò)展的好處
- 比起直接修改MBG源代碼,這種方式對MBG無代碼侵入,方便將來升級MBG。
- 符合面向?qū)ο笤O(shè)計(jì)的【開閉原則】,即通過增加代碼來為軟件添加新功能,而不是直接修改原有代碼。這一點(diǎn),MBG做得非常好,除了可以非常方便的擴(kuò)展之外,還可以寫各種插件以實(shí)現(xiàn)自己的業(yè)務(wù)需要。
使用自己的擴(kuò)展類
在配置文件 generatorConfig.xml 的 context 節(jié)點(diǎn),配置 targetRuntime 值,指向自己的擴(kuò)展類,需要帶包名,如本例:
<context id="Mysql" targetRuntime="mybatis.generator.enhance.IntrospectedTableEnhanceImpl" defaultModelType="flat">
擴(kuò)展類的代碼很簡單,只有十幾行
import org.mybatis.generator.codegen.mybatis3.IntrospectedTableMyBatis3Impl;
public class IntrospectedTableEnhanceImpl extends IntrospectedTableMyBatis3Impl {
@Override
public String getFullyQualifiedTableNameAtRuntime() {
return getTableNameFromConfigFile();
}
@Override
public String getAliasedFullyQualifiedTableNameAtRuntime() {
return getTableNameFromConfigFile();
}
private String getTableNameFromConfigFile() {
String tableName = this.getTableConfiguration().getTableName();
return "`" + tableName + "`";
}
}
兩種運(yùn)行方式
以程序方式運(yùn)行
仿照官方的org.mybatis.generator.api.ShellRunner,寫一段代碼,以程序的方式運(yùn)行。本工程的代碼如下:
public class GeneratorEnhanceRun {
public static void main(String[] args) {
try {
List<String> warnings = new ArrayList<String>();
/**
* 初始化配置解析器
*/
ConfigurationParser cp = new ConfigurationParser(warnings);
/**
* 獲取配置文件信息
*/
FileInputStream fileInputStream = new FileInputStream(ConfigProperties.getValue("configFile"));
/**
* 調(diào)用配置解析器創(chuàng)建配置對象
*/
Configuration config = cp.parseConfiguration(fileInputStream);
/**
* shellcallback接口主要用來處理文件的創(chuàng)建和合并,傳入overwrite參數(shù);默認(rèn)的shellcallback是不支持文件合并的;
*/
DefaultShellCallback callback = new DefaultShellCallback(true);
/**
* 創(chuàng)建一個(gè)MyBatisGenerator對象。MyBatisGenerator類是真正用來執(zhí)行生成動(dòng)作的類
*/
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
/**
* 用System.out打印執(zhí)行過程
*/
ProgressCallback progressCallback = new VerboseProgressCallback();
/**
* 執(zhí)行生成操作
*/
myBatisGenerator.generate(progressCallback);
} catch (Exception e) {
e.printStackTrace();
}
}
}
本工程,直接運(yùn)行GeneratorEnhanceRun下的main方法,在運(yùn)行之前需要先修改resources目錄下的配置文件application.properties,將MBG運(yùn)行需要的配置文件路徑配置對。
configFile=C:/workspace/mbg/mybatis-generator/generatorConfig.xml
cmd窗口運(yùn)行jar文件
- 下MBG的jar包,傳送門,解壓,找到
mybatis-generator-1.3.7.jar備用。 - 將本模塊生成jar文件,生成的jar文件名
mybatis-generator-enhance.jar。 - 將兩個(gè)jar文件以及配置文件放到model與dal項(xiàng)目所在的目錄下,在 cmd 窗口執(zhí)行:
java -Dfile.encoding=UTF-8 -cp mybatis-generator-1.3.7.jar;mybatis-generator-enhance.jar org.mybatis.generator.api.ShellRunner -configfile generatorConfig.xml -overwrite
這里通過 -cp 指定需要用到的所有jar包,用分號隔開,這樣在運(yùn)行的時(shí)候才能找到相應(yīng)的類。
原理
簡單的說,就是自己的實(shí)現(xiàn)類IntrospectedTableEnhanceImpl繼承自MBG的一個(gè)具體實(shí)現(xiàn)類,重寫獲取表名的方法。
IntrospectedTable是MBG提供的一個(gè)比較基礎(chǔ)的擴(kuò)展類,相當(dāng)于可以重新定義一個(gè)runtime。如果要通過繼承IntrospectedTable完成擴(kuò)展,需要自己來實(shí)現(xiàn)生成XML和Java代碼的所有代碼,也可以直接繼承IntrospectedTableMyBatis3Impl,重寫自己需要的業(yè)務(wù)邏輯,本模塊就是直接繼承自該類。
要擴(kuò)展自己的業(yè)務(wù)邏輯,建議先仔細(xì)閱讀IntrospectedTableMyBatis3Impl和IntrospectedTableMyBatis3SimpleImpl,這兩個(gè)類用得多一些。
在MBG中,提供了幾種默認(rèn)的IntrospectedTable的實(shí)現(xiàn),其實(shí)在context上設(shè)置的runtime對應(yīng)的就是不同的IntrospectedTable的實(shí)現(xiàn),下面是幾種runtime和對應(yīng)的實(shí)現(xiàn)類:
- MyBatis3 (default):org.mybatis.generator.codegen.mybatis3.IntrospectedTableMyBatis3Impl
- MyBatis3Simple:org.mybatis.generator.codegen.mybatis3.IntrospectedTableMyBatis3SimpleImpl
- Ibatis2Java2:org.mybatis.generator.codegen.ibatis2.IntrospectedTableIbatis2Java2Impl
- Ibatis2Java5:org.mybatis.generator.codegen.ibatis2.IntrospectedTableIbatis2Java5Impl
MySQL 數(shù)據(jù)庫驅(qū)動(dòng)版本與數(shù)據(jù)庫版本問題
用高版本的數(shù)據(jù)庫驅(qū)動(dòng)mysql-connector-java 8.0.13連接低版本數(shù)據(jù)庫MySQL 5.7.23,會(huì)有以下問題:
- 報(bào)錯(cuò)
Cannot obtain primary key information from the database, generated objects may be incomplete ... - 生成的 mapper 缺少以下接口:
deleteByPrimaryKey selectByPrimaryKey updateByPrimaryKeySelective updateByPrimaryKey
解決
數(shù)據(jù)庫驅(qū)動(dòng)與數(shù)據(jù)庫版本匹配即可,作者在以下兩個(gè)版本(5.x與8.x)測試通過:
- 數(shù)據(jù)庫驅(qū)動(dòng)
mysql-connector-java 8.0.13連接數(shù)據(jù)庫MySQL 8.0.11,對應(yīng)driverClassName: com.mysql.cj.jdbc.Driver - 數(shù)據(jù)庫驅(qū)動(dòng)
mysql-connector-java 5.1.29連接數(shù)據(jù)庫MySQL 5.7.23,對應(yīng)driverClassName: com.mysql.jdbc.Driver
本工程的數(shù)據(jù)庫驅(qū)動(dòng)版本,使用的是當(dāng)前最新的mysql-connector-java 8.0.13,僅支持連接高版本MySQL 8.x。
如果要在MySQL 5.7.x下運(yùn)行,只需要修改以下兩個(gè)地方(注意是5.7.x,其它5.x版本沒測試):
- 修改pom.xml中
mysql-connector.version,改為低版本5.1.39。 - 本項(xiàng)目的執(zhí)行,依賴根目錄下的
generatorConfig.xml文件,將其中driverClass,由com.mysql.cj.jdbc.Driver改為com.mysql.jdbc.Driver。