MyBatis Generator 程式碼自動生成器,從此解放你的雙手

村雨遙發表於2021-12-14

前言

在日常開發工作中,我們往往需要自己去構建各種資料表所對應的持久化物件(PO)、用於運算元據庫的介面(DAO)以及跟 DAO 所繫結的對應 XML。這都是一些重複性的操作,不需要多大技術含量,這時候我們不禁會去想,有沒有一種工具,能夠幫助我們去自動生成這些檔案呢?答案是:有的!

本文接下來的內容主要適用於使用 MyBatis 來做持久層框架開發的工作,如果不是使用 MyBatis,那麼可能本文不太適合你的開發場景。

MyBatis Generator 簡介

作為一個基於 MyBatis 的獨立工具,MyBatis Generator 能夠滿足我們以上的要求,能夠通過簡單的配置去幫我們生成資料表所對應的 PO、DAO、XML 等檔案,減去我們手動去生成這些檔案的時間,有效提高開發效率。MyBatis Generator 執行方式多樣,主要可以通過以下幾種方式來執行:

  1. 命令列
  2. Ant
  3. Maven
  4. Java
  5. 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 中的主要配置主要有以下幾點。

  1. 程式碼生成器的配置檔案所在路徑

這裡主要配置 MyBatis Generator 配置檔案所在路徑,一般我們將其放在 resources 路徑中,而配置檔案的名字則可以自定義,這裡我以 mybatis-generator-config.xml 為例,此時需要將如下配置加入到 pom.xml 檔案中。

<configuration>
    <configurationFile>src/main/resources/mybatis-generator-config.xml</configurationFile>
</configuration>

  1. 是否每次新生成後覆蓋已生成的檔案

由於專案需求,假設我們的資料庫表中有需要新增新的欄位,而我們之前已經使用過 MyBatis Generator 生成過相關檔案。此時,如果我們想要將新加的欄位加入原來生成的檔案中,第一種可以採取手動的方式,將舊檔案刪除,然後重新生成。第二種則是在 MyBatis Generator 中配置,讓每次新生成的檔案都直接覆蓋掉舊檔案。具體配置如下,true 則代表覆蓋,false 則代表不覆蓋。

<configuration>
    <overwrite>true</overwrite>
</configuration>

不過有一點需要注意,就算我們設定了覆蓋舊檔案,MyBatis Generator 也只會覆蓋原來的 PO、DAO 檔案,此時 Mapper 不會被覆蓋,而是採取追加的方式,從而保證我們自己新增的 sql 語句不會被覆蓋掉。

  1. 資料庫驅動依賴

雖然在專案的 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 進行具體配置,配置我們生成程式碼中的各種細節。

  1. 外部配置檔案

一般我們需要引入外部檔案,主要用於配置專案資料庫,方便我們後續的設定,而引入外部配置檔案的方式也很簡單,具體配置如下:

<generatorConfiguration>
    <!-- 引入配置檔案 -->
    <properties resource="generator.properties"/>
</generatorConfiguration>
  1. 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 除了上面配置的之外,還有許多子元素需要配置,而且這些子元素的配置的個數以及順序都是規定好的,如果不按照給定的規則進行配置,則會導致錯誤,常見子元素及個數配置如下(按照規定的順序進行從上到下排序):

子元素最少個數最多個數
property0N
plugin0N
commentGenerator01
jdbcConnection
javaTypeResolver01
javaModelGenerator1N
sqlMapGenerator01
javaClientGenerator01
table1N

接下來依次對各個子元素進行簡單的配置講解。

context 子元素配置

  1. property

如果我們要給我們的所生成檔案的編碼型別進行設定,則可以在此處進行配置,具體配置如下:

<property name="javaFileEncoding" value="UTF-8"/>
  1. plugin

預設生成的 PO 中,只包含了各個各個屬性宣告以及各個屬性所對應的 setter/getter,如果我們想要生成對應 PO 的 equalshashCode 方法,則可以通過配置如下外掛來實現。

<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>

要生成 toString 方法,則可以使用如下外掛:

<plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>

為模型生成序列化方法,則使用如下外掛:

<plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
  1. 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>
  1. 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>
  1. javaTypeResolver

主要用於配置 JDBC 和 Java 中的型別轉換規則,如果我們不配置,會採用預設的一套轉換規則,而如果我們需要自定義,也只能配置 bigDecimalNUMERIC 和時間型別,不能去配置其他型別,否則會導致出錯,具體配置規則如下:

<javaTypeResolver>
    <property name="forceBigDecimals" value="true"/>
    <property name="useJSR310Types" value="false"/>
</javaTypeResolver>
  • forceBigDecimals

該屬性預設為 false,此時它會將 JDBC DECIMALNUMERIC 型別解析為 Integer,若該屬性為 true,此時將會把 JDBC DECIMALNUMERIC 型別解析為 java.math.BigDecimal

  • useJSR310Types

該屬性預設為 false,它會將 JDBC 所有的時間型別都解析為 java.util.Date,若該屬性為 true,則會按照如下規則進行解析:

轉換前轉換後
DATEjava.time.LocalDate
TIMEjava.time.LocalTime
TIMESTAMPjava.time.LocalDateTime
TIME_WITH_TIMEZONEjava.time.OffsetTime
TIMESTAMP_WITH_TIMEZONEjava.time.OffsetDateTime
  1. 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>
  1. sqlMapGenerator

配置生成的 Mapper.xml 所存放的路徑,比如我們要放在 src/main/resources/mapper 路徑下,則配置如下:

<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
</sqlMapGenerator>
  1. javaClientGenerator

配置 Mapper 介面所存放的路徑,一般我們都是存放在專案的 mapper 包下,如我的配置為:

<javaClientGenerator targetPackage="com.cunyu1943.mybatisgeneratordemo.mapper" targetProject="src/main/java"
                     type="XMLMAPPER">
</javaClientGenerator>
  1. 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

相關文章