MyBatis Generator 代碼自動(dòng)生成器,從此解放你的雙手
1前言
在日常開(kāi)發(fā)工作中,我們往往需要自己去構(gòu)建各種數(shù)據(jù)表所對(duì)應(yīng)的持久化對(duì)象(PO)、用于操作數(shù)據(jù)庫(kù)的接口(DAO)以及跟 DAO 所綁定的對(duì)應(yīng) XML。這都是一些重復(fù)性的操作,不需要多大技術(shù)含量,這時(shí)候我們不禁會(huì)去想,有沒(méi)有一種工具,能夠幫助我們?nèi)プ詣?dòng)生成這些文件呢?答案是:有的!
本文接下來(lái)的內(nèi)容主要適用于使用 MyBatis 來(lái)做持久層框架開(kāi)發(fā)的工作,如果不是使用 MyBatis,那么可能本文不太適合你的開(kāi)發(fā)場(chǎng)景。
2MyBatis Generator 簡(jiǎn)介
作為一個(gè)基于 MyBatis 的獨(dú)立工具,MyBatis Generator 能夠滿足我們以上的要求,能夠通過(guò)簡(jiǎn)單的配置去幫我們生成數(shù)據(jù)表所對(duì)應(yīng)的 PO、DAO、XML 等文件,減去我們手動(dòng)去生成這些文件的時(shí)間,有效提高開(kāi)發(fā)效率。MyBatis Generator 運(yùn)行方式多樣,主要可以通過(guò)以下幾種方式來(lái)運(yùn)行:
命令行 Ant Maven Java Eclipse
而我平時(shí)主要在 Maven 中配置并使用,所以本文主要基于 Maven 環(huán)境來(lái)進(jìn)行講解。
3準(zhǔn)備工作
引入插件
既然要使用 MyBatis Generator,那么肯定我們的項(xiàng)目中已經(jīng)配置了數(shù)據(jù)庫(kù)和 MyBatis 的相關(guān)依賴,如果還沒(méi)有配置,那么可以在 pom.xml 文件中進(jìn)行配置,這里主要以 MySQL 數(shù)據(jù)庫(kù)為例。
<dependencies>
????<dependency>
????????<groupId>mysqlgroupId>
????????<artifactId>mysql-connector-javaartifactId>
????dependency>
????<dependency>
????????<groupId>org.mybatis.spring.bootgroupId>
????????<artifactId>mybatis-spring-boot-starterartifactId>
????dependency>
dependencies>
接著我們繼續(xù)引入 MyBatis Generator 的相關(guān)配置。
<build>
????<plugins>
????????<plugin>
????????????<groupId>org.mybatis.generatorgroupId>
????????????<artifactId>mybatis-generator-maven-pluginartifactId>
????????????<version>1.4.0version>
????????plugin>
????plugins>
build>
插件配置
完成上述步驟后,我們只是完成了 MyBatis Generator 的引入工作,要想讓它正常工作,我們還需要對(duì)它進(jìn)行配置,而 MyBatis Generator 在 pom.xml 中的主要配置主要有以下幾點(diǎn)。
代碼生成器的配置文件所在路徑
這里主要配置 MyBatis Generator 配置文件所在路徑,一般我們將其放在 resources 路徑中,而配置文件的名字則可以自定義,這里我以 mybatis-generator-config.xml 為例,此時(shí)需要將如下配置加入到 pom.xml 文件中。
<configuration>
????<configurationFile>src/main/resources/mybatis-generator-config.xmlconfigurationFile>
configuration>

是否每次新生成后覆蓋已生成的文件
由于項(xiàng)目需求,假設(shè)我們的數(shù)據(jù)庫(kù)表中有需要新增新的字段,而我們之前已經(jīng)使用過(guò) MyBatis Generator 生成過(guò)相關(guān)文件。此時(shí),如果我們想要將新加的字段加入原來(lái)生成的文件中,第一種可以采取手動(dòng)的方式,將舊文件刪除,然后重新生成。第二種則是在 MyBatis Generator 中配置,讓每次新生成的文件都直接覆蓋掉舊文件。具體配置如下,true 則代表覆蓋,false 則代表不覆蓋。
<configuration>
????<overwrite>trueoverwrite>
configuration>
不過(guò)有一點(diǎn)需要注意,就算我們?cè)O(shè)置了覆蓋舊文件,MyBatis Generator 也只會(huì)覆蓋原來(lái)的 PO、DAO 文件,此時(shí) Mapper 不會(huì)被覆蓋,而是采取追加的方式,從而保證我們自己添加的 sql 語(yǔ)句不會(huì)被覆蓋掉。
數(shù)據(jù)庫(kù)驅(qū)動(dòng)依賴
雖然在項(xiàng)目的 pom.xml 文件中我們已經(jīng)配置了數(shù)據(jù)庫(kù)的相關(guān)依賴,但是在 MyBatis Generator 配置中仍然需要對(duì)其進(jìn)行再次配置。此時(shí),這里有兩種方式供我們選擇。
第一種是再次在引入數(shù)據(jù)庫(kù)依賴,具體配置方式如下:
<build>
????<plugins>
????????<plugin>
????????????<groupId>org.mybatis.generatorgroupId>
????????????<artifactId>mybatis-generator-maven-pluginartifactId>
????????????<version>1.4.0version>
????????????<dependencies>
????????????????<dependency>
????????????????????<groupId>mysqlgroupId>
????????????????????<artifactId>mysql-connector-javaartifactId>
????????????????????<version>8.0.17version>
????????????????dependency>
????????????dependencies>
????????plugin>
????plugins>
build>
第二種則是利用 Maven 的 includeCompileDependencies 屬性。一般來(lái)講,我們的項(xiàng)目中肯定已經(jīng)引入過(guò)數(shù)據(jù)庫(kù)的相關(guān)依賴了,那我們此時(shí)配置 includeCompileDependencies 就好了,具體配置方式如下:
<configuration>
????<includeCompileDependencies>trueincludeCompileDependencies>
configuration>
MyBatis Generator 配置
我們?cè)谏鲜霾襟E中已經(jīng)引入了 MyBatis Generator,而且也在項(xiàng)目配置文件 pom.xml 中配置了 MyBatis Generator 配置文件所在的路徑、是否進(jìn)行文件覆蓋以及數(shù)據(jù)庫(kù)依賴配置,接下來(lái)就該具體來(lái)看看,如何對(duì) MyBatis Generator 進(jìn)行具體配置,配置我們生成代碼中的各種細(xì)節(jié)。
外部配置文件
一般我們需要引入外部文件,主要用于配置項(xiàng)目數(shù)據(jù)庫(kù),方便我們后續(xù)的設(shè)置,而引入外部配置文件的方式也很簡(jiǎn)單,具體配置如下:
<generatorConfiguration>
????
????<properties?resource="generator.properties"/>
generatorConfiguration>
context 配置
除開(kāi)外部配置外,context 無(wú)疑是 MyBatis Generator 中最重要的配置了。一個(gè) context 配置的具體示例如下:
<context?id="myContext"?targetRuntime="MyBatis3"?defaultModelType="flat">
context>
其中的各個(gè)屬性含義如下:
id:唯一標(biāo)識(shí),不可重復(fù),可以根據(jù)我們自己的喜好進(jìn)行自定義。 defaultModelType:非必填項(xiàng),有兩個(gè)值可選,一個(gè)是 conditional,也是默認(rèn)值,另一個(gè)值是flat,也就是我們常用的一個(gè)配置,表示數(shù)據(jù)庫(kù)中的一張表對(duì)應(yīng)生成一個(gè) PO。targetRuntime:非必填項(xiàng),這里同樣有兩個(gè)值可選,一個(gè)是 MyBatis3,一個(gè)是MyBatis3Simple,兩者的最主要區(qū)別在于不同配置下所生成的 DAO 和 Mapper 會(huì)有所不同,后者生成的 DAO 和 Mapper 會(huì)少很多,只含有日常最常用的。
context 除了上面配置的之外,還有許多子元素需要配置,而且這些子元素的配置的個(gè)數(shù)以及順序都是規(guī)定好的,如果不按照給定的規(guī)則進(jìn)行配置,則會(huì)導(dǎo)致錯(cuò)誤,常見(jiàn)子元素及個(gè)數(shù)配置如下(按照規(guī)定的順序進(jìn)行從上到下排序):
| 子元素 | 最少個(gè)數(shù) | 最多個(gè)數(shù) |
|---|---|---|
property | 0 | N |
plugin | 0 | N |
commentGenerator | 0 | 1 |
jdbcConnection | ||
javaTypeResolver | 0 | 1 |
javaModelGenerator | 1 | N |
sqlMapGenerator | 0 | 1 |
javaClientGenerator | 0 | 1 |
table | 1 | N |
接下來(lái)依次對(duì)各個(gè)子元素進(jìn)行簡(jiǎn)單的配置講解。
context 子元素配置
property
如果我們要給我們的所生成文件的編碼類(lèi)型進(jìn)行設(shè)置,則可以在此處進(jìn)行配置,具體配置如下:
<property?name="javaFileEncoding"?value="UTF-8"/>
plugin
默認(rèn)生成的 PO 中,只包含了各個(gè)各個(gè)屬性聲明以及各個(gè)屬性所對(duì)應(yīng)的 setter/getter,如果我們想要生成對(duì)應(yīng) PO 的 equals 和 hashCode 方法,則可以通過(guò)配置如下插件來(lái)實(shí)現(xiàn)。
<plugin?type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>
要生成 toString 方法,則可以使用如下插件:
<plugin?type="org.mybatis.generator.plugins.ToStringPlugin"/>
為模型生成序列化方法,則使用如下插件:
<plugin?type="org.mybatis.generator.plugins.SerializablePlugin"/>
commentGenerator
該配置主要用于配置生成的注釋?zhuān)J(rèn)情況下是會(huì)生成注釋的,而且會(huì)帶上時(shí)間戳,如果我們不需要這些配置,則可以通過(guò)如下配置來(lái)清除:
<commentGenerator>
????
????<property?name="suppressAllComments"?value="true"/>
????
????<property?name="suppressDate"?value="true"/>
????
????<property?name="addRemarkComments"?value="true"/>
commentGenerator>
jdbcConnection
既然要自動(dòng)生成對(duì)應(yīng)文件,那肯定得鏈接數(shù)據(jù)庫(kù),所以我們需要對(duì)數(shù)據(jù)庫(kù)進(jìn)行配置,上面我們講過(guò)導(dǎo)入外部配置文件,我們可以通過(guò)這種方式將數(shù)據(jù)庫(kù)的配置定義在外部文件中,然后通過(guò)導(dǎo)入該文件進(jìn)行配置即可,具體可以通過(guò)如下具體步驟進(jìn)行:
<jdbcConnection?driverClass="${jdbc.driver-class-name}"
????????????????connectionURL="${jdbc.url}"
????????????????userId="${jdbc.username}"
????????????????password="${jdbc.password}">
????
????<property?name="nullCatalogMeansCurrent"?value="true"/>
jdbcConnection>
javaTypeResolver
主要用于配置 JDBC 和 Java 中的類(lèi)型轉(zhuǎn)換規(guī)則,如果我們不配置,會(huì)采用默認(rèn)的一套轉(zhuǎn)換規(guī)則,而如果我們需要自定義,也只能配置 bigDecimal、NUMERIC 和時(shí)間類(lèi)型,不能去配置其他類(lèi)型,否則會(huì)導(dǎo)致出錯(cuò),具體配置規(guī)則如下:
<javaTypeResolver>
????<property?name="forceBigDecimals"?value="true"/>
????<property?name="useJSR310Types"?value="false"/>
javaTypeResolver>
forceBigDecimals
該屬性默認(rèn)為 false,此時(shí)它會(huì)將 JDBC DECIMAL 和 NUMERIC 類(lèi)型解析為 Integer,若該屬性為 true,此時(shí)將會(huì)把 JDBC DECIMAL 和 NUMERIC 類(lèi)型解析為 java.math.BigDecimal。
useJSR310Types
該屬性默認(rèn)為 false,它會(huì)將 JDBC 所有的時(shí)間類(lèi)型都解析為 java.util.Date,若該屬性為 true,則會(huì)按照如下規(guī)則進(jìn)行解析:
| 轉(zhuǎn)換前 | 轉(zhuǎn)換后 |
|---|---|
DATE | java.time.LocalDate |
TIME | java.time.LocalTime |
TIMESTAMP | java.time.LocalDateTime |
TIME_WITH_TIMEZONE | java.time.OffsetTime |
TIMESTAMP_WITH_TIMEZONE | java.time.OffsetDateTime |
javaModelGenerator
這里主要用于配置自動(dòng)生成的 PO 所在的包路徑和項(xiàng)目路徑,這里需要根據(jù)自己的需求進(jìn)行配置,這里以我自己的配置為例,比如我的 PO 所在包為 com.cunyu1943.mybatisgeneratordemo.entity,項(xiàng)目路徑為 src/main/java。
<javaModelGenerator?targetPackage="com.cunyu1943.mybatisgeneratordemo.entity"?targetProject="src/main/java">
????
????<property?name="enableSubPackages"?value="false"/>
????
????<property?name="trimStrings"?value="true"/>
javaModelGenerator>
sqlMapGenerator
配置生成的 Mapper.xml 所存放的路徑,比如我們要放在 src/main/resources/mapper 路徑下,則配置如下:
<sqlMapGenerator?targetPackage="mapper"?targetProject="src/main/resources">
sqlMapGenerator>
javaClientGenerator
配置 Mapper 接口所存放的路徑,一般我們都是存放在項(xiàng)目的 mapper 包下,如我的配置為:
<javaClientGenerator?targetPackage="com.cunyu1943.mybatisgeneratordemo.mapper"?targetProject="src/main/java"
?????????????????????type="XMLMAPPER">
javaClientGenerator>
table
配置所要自動(dòng)生成代碼的數(shù)據(jù)庫(kù)表,這里一張表對(duì)應(yīng)一個(gè) table,如果要生成多張表,則需要配置多個(gè) table,以下為一個(gè)具體實(shí)例:
<table?schema=""?tableName="user"?domainObjectName="User"
???????enableCountByExample="false"?enableDeleteByExample="false"?enableSelectByExample="false"
???????enableUpdateByExample="false"?selectByExampleQueryId="false">
????
????<property?name="useActualColumnNames"?value="false"?/>
table>
其中,schema 是數(shù)據(jù)庫(kù)名,有的數(shù)據(jù)庫(kù)需要配置,有的數(shù)據(jù)庫(kù)不需要配置,這里需要具體根據(jù)你自己所用的數(shù)據(jù)庫(kù)來(lái)填寫(xiě),不過(guò)建議都填上,方便不同數(shù)據(jù)庫(kù)也可以適用。tableName 則對(duì)應(yīng)數(shù)據(jù)庫(kù)表名;domainObjectName 對(duì)應(yīng)生成的實(shí)體類(lèi)名,默認(rèn)可以不用配置,不配置時(shí)它將按照帕斯卡命名法將表明轉(zhuǎn)換為類(lèi)名;而 enableXXXByExample 默認(rèn)為 true,默認(rèn)會(huì)生成一個(gè) Example 幫助類(lèi),不過(guò)該配置只有在 targetRuntime="MyBatis3" 時(shí)才能生效,當(dāng) targetRuntime="MyBatis3Simple" 時(shí),enableXXXByExample 無(wú)論如何配置都不起作用。
4執(zhí)行生成
經(jīng)過(guò)上邊的配置之后,我們就得到了整體的 MyBatis Generator 配置,完整的配置如下,可以根據(jù)自己的需求對(duì)其中的配置進(jìn)行修改后即可使用。
generatorConfiguration
????????PUBLIC?"-//mybatis.org//DTD?MyBatis?Generator?Configuration?1.0//EN"
????????"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
????
????<properties?resource="generator.properties"/>
????
????<context?id="myContext"?targetRuntime="MyBatis3Simple"?defaultModelType="flat">
????????
????????<property?name="javaFileEncoding"?value="UTF-8"/>
????????
????????<plugin?type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>
????????
????????<plugin?type="org.mybatis.generator.plugins.ToStringPlugin"/>
????????
????????<plugin?type="org.mybatis.generator.plugins.SerializablePlugin"/>
????????
????????<commentGenerator>
????????????
????????????<property?name="suppressAllComments"?value="true"/>
????????????
????????????<property?name="suppressDate"?value="true"/>
????????????
????????????<property?name="addRemarkComments"?value="true"/>
????????commentGenerator>
????????
????????<jdbcConnection?driverClass="${jdbc.driver-class-name}"
????????????????????????connectionURL="${jdbc.url}"
????????????????????????userId="${jdbc.username}"
????????????????????????password="${jdbc.password}">
????????????
????????????<property?name="nullCatalogMeansCurrent"?value="true"/>
????????jdbcConnection>
????????
????????<javaTypeResolver>
????????????
????????????<property?name="forceBigDecimals"?value="true"/>
????????????
????????????<property?name="useJSR310Types"?value="false"/>
????????javaTypeResolver>
????????
????????<javaModelGenerator?targetPackage="com.cunyu1943.mybatisgeneratordemo.entity"?targetProject="src/main/java">
????????????
????????????<property?name="enableSubPackages"?value="false"/>
????????????
????????????<property?name="trimStrings"?value="true"/>
????????javaModelGenerator>
????????
????????<sqlMapGenerator?targetPackage="mapper"?targetProject="src/main/resources">
????????sqlMapGenerator>
????????
????????<javaClientGenerator?targetPackage="com.cunyu1943.mybatisgeneratordemo.mapper"?targetProject="src/main/java"
?????????????????????????????type="XMLMAPPER">
????????javaClientGenerator>
????????
????????<table?schema=""?tableName="user"?domainObjectName="User"
???????????????enableCountByExample="false"?enableDeleteByExample="false"?enableSelectByExample="false"
???????????????enableUpdateByExample="false"?selectByExampleQueryId="false">
????????????
????????????<property?name="useActualColumnNames"?value="false"/>
????????table>
????context>
generatorConfiguration>
其中,關(guān)于外部文件 generator.properties 的配置具體如下,主要對(duì)數(shù)據(jù)庫(kù)的相關(guān)屬性進(jìn)行配置。
jdbc.username=root
jdbc.password=123456
jdbc.url=jdbc:mysql://localhost:3306/community?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
jdbc.driver-class-name=com.mysql.cj.jdbc.Driver
最后,當(dāng)完成所有配置后,就可以利用 Maven 工具來(lái)進(jìn)行代碼生成了。具體操作方法如下,點(diǎn)擊項(xiàng)目 Maven 配置中的 MyBatis Generator 生成即可。

5總結(jié)
以上就是利用 Maven 搭配 MyBatis Generator 來(lái)配置生成項(xiàng)目 PO、Mapper、XXXMapper.xml 的具體搭建過(guò)程了。如果你也剛好有這個(gè)需求,那趕緊去試試吧。搭建過(guò)程中如果遇到什么問(wèn)題,歡迎評(píng)論區(qū)留言交流,我會(huì)在看到的第一時(shí)間回復(fù)。
最后,關(guān)于本示例的相關(guān)代碼,我已經(jīng)傳到了 Github,如果有需要的兄弟,可以自取。
?????? 傳送門(mén) -> mybatis-generator-demo[1]
參考資料
mybatis-generator-demo: https://github.com/cunyu1943/java-learning-demos/tree/main/mybatis-generator-demo
