前言
在日常開發工作中,我們往往需要自己去構建各種資料表所對應的持久化物件(PO)、用於運算元據庫的介面(DAO)以及跟 DAO 所繫結的對應 XML。這都是一些重複性的操作,不需要多大技術含量,這時候我們不禁會去想,有沒有一種工具,能夠幫助我們去自動生成這些檔案呢?答案是:有的!
本文接下來的內容主要適用於使用 MyBatis 來做持久層框架開發的工作,如果不是使用 MyBatis,那麼可能本文不太適合你的開發場景。
MyBatis Generator 簡介
作為一個基於 MyBatis 的獨立工具,MyBatis Generator 能夠滿足我們以上的要求,能夠通過簡單的配置去幫我們生成資料表所對應的 PO、DAO、XML 等檔案,減去我們手動去生成這些檔案的時間,有效提高開發效率。MyBatis Generator 執行方式多樣,主要可以通過以下幾種方式來執行:
- 命令列
- Ant
- Maven
- Java
- Eclipse
而我平時主要在 Maven 中配置並使用,所以本文主要基於 Maven 環境來進行講解。
準備工作
引入外掛
既然要使用 MyBatis Generator,那麼肯定我們的專案中已經配置了資料庫和 MyBatis 的相關依賴,如果還沒有配置,那麼可以在 pom.xml
檔案中進行配置,這裡主要以 MySQL 資料庫為例。
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
</dependencies>
接著我們繼續引入 MyBatis Generator 的相關配置。
<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.0</version>
</plugin>
</plugins>
</build>
外掛配置
完成上述步驟後,我們只是完成了 MyBatis Generator 的引入工作,要想讓它正常工作,我們還需要對它進行配置,而 MyBatis Generator 在 pom.xml
中的主要配置主要有以下幾點。
- 程式碼生成器的配置檔案所在路徑
這裡主要配置 MyBatis Generator 配置檔案所在路徑,一般我們將其放在 resources
路徑中,而配置檔案的名字則可以自定義,這裡我以 mybatis-generator-config.xml
為例,此時需要將如下配置加入到 pom.xml
檔案中。
<configuration>
<configurationFile>src/main/resources/mybatis-generator-config.xml</configurationFile>
</configuration>
- 是否每次新生成後覆蓋已生成的檔案
由於專案需求,假設我們的資料庫表中有需要新增新的欄位,而我們之前已經使用過 MyBatis Generator 生成過相關檔案。此時,如果我們想要將新加的欄位加入原來生成的檔案中,第一種可以採取手動的方式,將舊檔案刪除,然後重新生成。第二種則是在 MyBatis Generator 中配置,讓每次新生成的檔案都直接覆蓋掉舊檔案。具體配置如下,true
則代表覆蓋,false
則代表不覆蓋。
<configuration>
<overwrite>true</overwrite>
</configuration>
不過有一點需要注意,就算我們設定了覆蓋舊檔案,MyBatis Generator 也只會覆蓋原來的 PO、DAO 檔案,此時 Mapper 不會被覆蓋,而是採取追加的方式,從而保證我們自己新增的 sql 語句不會被覆蓋掉。
- 資料庫驅動依賴
雖然在專案的 pom.xml
檔案中我們已經配置了資料庫的相關依賴,但是在 MyBatis Generator 配置中仍然需要對其進行再次配置。此時,這裡有兩種方式供我們選擇。
第一種是再次在引入資料庫依賴,具體配置方式如下:
<build>
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.0</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
第二種則是利用 Maven 的 includeCompileDependencies
屬性。一般來講,我們的專案中肯定已經引入過資料庫的相關依賴了,那我們此時配置 includeCompileDependencies
就好了,具體配置方式如下:
<configuration>
<includeCompileDependencies>true</includeCompileDependencies>
</configuration>
MyBatis Generator 配置
我們在上述步驟中已經引入了 MyBatis Generator,而且也在專案配置檔案 pom.xml
中配置了 MyBatis Generator 配置檔案所在的路徑、是否進行檔案覆蓋以及資料庫依賴配置,接下來就該具體來看看,如何對 MyBatis Generator 進行具體配置,配置我們生成程式碼中的各種細節。
- 外部配置檔案
一般我們需要引入外部檔案,主要用於配置專案資料庫,方便我們後續的設定,而引入外部配置檔案的方式也很簡單,具體配置如下:
<generatorConfiguration>
<!-- 引入配置檔案 -->
<properties resource="generator.properties"/>
</generatorConfiguration>
- context 配置
除開外部配置外,context
無疑是 MyBatis Generator 中最重要的配置了。一個 context
配置的具體示例如下:
<context id="myContext" targetRuntime="MyBatis3" defaultModelType="flat">
</context>
其中的各個屬性含義如下:
- id:唯一標識,不可重複,可以根據我們自己的喜好進行自定義。
- defaultModelType:非必填項,有兩個值可選,一個是
conditional
,也是預設值,另一個值是flat
,也就是我們常用的一個配置,表示資料庫中的一張表對應生成一個 PO。 - targetRuntime:非必填項,這裡同樣有兩個值可選,一個是
MyBatis3
,一個是MyBatis3Simple
,兩者的最主要區別在於不同配置下所生成的 DAO 和 Mapper 會有所不同,後者生成的 DAO 和 Mapper 會少很多,只含有日常最常用的。
context
除了上面配置的之外,還有許多子元素需要配置,而且這些子元素的配置的個數以及順序都是規定好的,如果不按照給定的規則進行配置,則會導致錯誤,常見子元素及個數配置如下(按照規定的順序進行從上到下排序):
子元素 | 最少個數 | 最多個數 |
---|---|---|
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 |
接下來依次對各個子元素進行簡單的配置講解。
context 子元素配置
- property
如果我們要給我們的所生成檔案的編碼型別進行設定,則可以在此處進行配置,具體配置如下:
<property name="javaFileEncoding" value="UTF-8"/>
- plugin
預設生成的 PO 中,只包含了各個各個屬性宣告以及各個屬性所對應的 setter/getter
,如果我們想要生成對應 PO 的 equals
和 hashCode
方法,則可以通過配置如下外掛來實現。
<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>
要生成 toString
方法,則可以使用如下外掛:
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
為模型生成序列化方法,則使用如下外掛:
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
- commentGenerator
該配置主要用於配置生成的註釋,預設情況下是會生成註釋的,而且會帶上時間戳,如果我們不需要這些配置,則可以通過如下配置來清除:
<commentGenerator>
<!-- 是否去除自動生成的註釋 true:是 : false:否 -->
<property name="suppressAllComments" value="true"/>
<!-- 是否去除自動生成的時間戳 true:是 : false:否 -->
<property name="suppressDate" value="true"/>
<!-- 是否新增資料庫表中欄位的註釋 true:是 : false:否,只有當suppressAllComments 為 false 時才能生效 -->
<property name="addRemarkComments" value="true"/>
</commentGenerator>
- jdbcConnection
既然要自動生成對應檔案,那肯定得連結資料庫,所以我們需要對資料庫進行配置,上面我們講過匯入外部配置檔案,我們可以通過這種方式將資料庫的配置定義在外部檔案中,然後通過匯入該檔案進行配置即可,具體可以通過如下具體步驟進行:
<jdbcConnection driverClass="${jdbc.driver-class-name}"
connectionURL="${jdbc.url}"
userId="${jdbc.username}"
password="${jdbc.password}">
<!--高版本的 mysql-connector-java 需要設定 nullCatalogMeansCurrent=true-->
<property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>
- javaTypeResolver
主要用於配置 JDBC 和 Java 中的型別轉換規則,如果我們不配置,會採用預設的一套轉換規則,而如果我們需要自定義,也只能配置 bigDecimal
、NUMERIC
和時間型別,不能去配置其他型別,否則會導致出錯,具體配置規則如下:
<javaTypeResolver>
<property name="forceBigDecimals" value="true"/>
<property name="useJSR310Types" value="false"/>
</javaTypeResolver>
- forceBigDecimals
該屬性預設為 false
,此時它會將 JDBC DECIMAL
和 NUMERIC
型別解析為 Integer
,若該屬性為 true
,此時將會把 JDBC DECIMAL
和 NUMERIC
型別解析為 java.math.BigDecimal
。
- useJSR310Types
該屬性預設為 false
,它會將 JDBC 所有的時間型別都解析為 java.util.Date
,若該屬性為 true
,則會按照如下規則進行解析:
轉換前 | 轉換後 |
---|---|
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
這裡主要用於配置自動生成的 PO 所在的包路徑和專案路徑,這裡需要根據自己的需求進行配置,這裡以我自己的配置為例,比如我的 PO 所在包為 com.cunyu1943.mybatisgeneratordemo.entity
,專案路徑為 src/main/java
。
<javaModelGenerator targetPackage="com.cunyu1943.mybatisgeneratordemo.entity" targetProject="src/main/java">
<!-- 是否讓 schema 作為包的字尾,預設為 false -->
<property name="enableSubPackages" value="false"/>
<!-- 是否針對 String 型別的欄位在 set 方法中進行修剪,預設 false -->
<property name="trimStrings" value="true"/>
</javaModelGenerator>
- sqlMapGenerator
配置生成的 Mapper.xml
所存放的路徑,比如我們要放在 src/main/resources/mapper
路徑下,則配置如下:
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
</sqlMapGenerator>
- javaClientGenerator
配置 Mapper
介面所存放的路徑,一般我們都是存放在專案的 mapper
包下,如我的配置為:
<javaClientGenerator targetPackage="com.cunyu1943.mybatisgeneratordemo.mapper" targetProject="src/main/java"
type="XMLMAPPER">
</javaClientGenerator>
- table
配置所要自動生成程式碼的資料庫表,這裡一張表對應一個 table
,如果要生成多張表,則需要配置多個 table
,以下為一個具體例項:
<table schema="" tableName="user" domainObjectName="User"
enableCountByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
enableUpdateByExample="false" selectByExampleQueryId="false">
<!--是否使用實際列名,預設為false-->
<property name="useActualColumnNames" value="false" />
</table>
其中,schema
是資料庫名,有的資料庫需要配置,有的資料庫不需要配置,這裡需要具體根據你自己所用的資料庫來填寫,不過建議都填上,方便不同資料庫也可以適用。tableName
則對應資料庫表名;domainObjectName
對應生成的實體類名,預設可以不用配置,不配置時它將按照帕斯卡命名法將表明轉換為類名;而 enableXXXByExample
預設為 true
,預設會生成一個 Example
幫助類,不過該配置只有在 targetRuntime="MyBatis3"
時才能生效,當 targetRuntime="MyBatis3Simple"
時,enableXXXByExample
無論如何配置都不起作用。
執行生成
經過上邊的配置之後,我們就得到了整體的 MyBatis Generator 配置,完整的配置如下,可以根據自己的需求對其中的配置進行修改後即可使用。
<?xml version="1.0" encoding="UTF-8" ?>
<!--mybatis的程式碼生成器相關配置-->
<!DOCTYPE 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,context的子元素必須按照它給出的順序
property*,plugin*,commentGenerator?,jdbcConnection,javaTypeResolver?,
javaModelGenerator,sqlMapGenerator?,javaClientGenerator?,table+
-->
<context id="myContext" targetRuntime="MyBatis3Simple" defaultModelType="flat">
<!-- 設定生成檔案的編碼-->
<property name="javaFileEncoding" value="UTF-8"/>
<!-- 這個外掛給生成的Java模型物件增加了equals和hashCode方法 -->
<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>
<!-- 增加 toString 方法-->
<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
<!-- 生成序列化方法-->
<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
<!-- 註釋 -->
<commentGenerator>
<!-- 是否生成註釋 true: 否: false: 是 -->
<property name="suppressAllComments" value="true"/>
<!-- 是否去除時間戳 true:是 : false:否 -->
<property name="suppressDate" value="true"/>
<!-- 是否新增資料庫表中欄位的註釋 true:是 : false:否,只有當suppressAllComments 為 false 時才能生效 -->
<property name="addRemarkComments" value="true"/>
</commentGenerator>
<!-- jdbc連線 -->
<jdbcConnection driverClass="${jdbc.driver-class-name}"
connectionURL="${jdbc.url}"
userId="${jdbc.username}"
password="${jdbc.password}">
<!--高版本的 mysql-connector-java 需要設定 nullCatalogMeansCurrent=true-->
<property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>
<!-- 型別轉換 -->
<javaTypeResolver>
<!--是否使用bigDecimal,預設false。
false,把JDBC DECIMAL 和 NUMERIC 型別解析為 Integer
true,把JDBC DECIMAL 和 NUMERIC 型別解析為java.math.BigDecimal-->
<property name="forceBigDecimals" value="true"/>
<!--預設 false
false,將所有 JDBC 的時間型別解析為 java.util.Date
true,將 JDBC 的時間型別按如下規則解析
DATE -> java.time.LocalDate
TIME -> java.time.LocalTime
TIMESTAMP -> java.time.LocalDateTime
TIME_WITH_TIMEZONE -> java.time.OffsetTime
TIMESTAMP_WITH_TIMEZONE -> java.time.OffsetDateTime
-->
<property name="useJSR310Types" value="false"/>
</javaTypeResolver>
<!-- 生成實體類地址 -->
<javaModelGenerator targetPackage="com.cunyu1943.mybatisgeneratordemo.entity" targetProject="src/main/java">
<!-- 是否讓 schema 作為包的字尾,預設為false -->
<property name="enableSubPackages" value="false"/>
<!-- 是否針對string型別的欄位在set方法中進行修剪,預設false -->
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- 生成Mapper.xml檔案 -->
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
</sqlMapGenerator>
<!-- 生成 XxxMapper.java 介面-->
<javaClientGenerator targetPackage="com.cunyu1943.mybatisgeneratordemo.mapper" targetProject="src/main/java"
type="XMLMAPPER">
</javaClientGenerator>
<!-- schema為資料庫名,oracle需要配置,mysql不需要配置。
tableName為對應的資料庫表名
domainObjectName 是要生成的實體類名(可以不指定,預設按帕斯卡命名法將表名轉換成類名)
enableXXXByExample 預設為 true, 為 true 會生成一個對應Example幫助類,幫助你進行條件查詢,不想要可以設為false
-->
<table schema="" tableName="user" domainObjectName="User"
enableCountByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
enableUpdateByExample="false" selectByExampleQueryId="false">
<!--是否使用實際列名,預設為false-->
<property name="useActualColumnNames" value="false"/>
</table>
</context>
</generatorConfiguration>
其中,關於外部檔案 generator.properties
的配置具體如下,主要對資料庫的相關屬性進行配置。
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
最後,當完成所有配置後,就可以利用 Maven 工具來進行程式碼生成了。具體操作方法如下,點選專案 Maven 配置中的 MyBatis Generator 生成即可。
總結
以上就是利用 Maven 搭配 MyBatis Generator 來配置生成專案 PO、Mapper、XXXMapper.xml 的具體搭建過程了。如果你也剛好有這個需求,那趕緊去試試吧。搭建過程中如果遇到什麼問題,歡迎評論區留言交流,我會在看到的第一時間回覆。
最後,關於本示例的相關程式碼,我已經傳到了 Github,如果有需要的兄弟,可以自取。
??? 傳送門 -> mybatis-generator-demo