MyBatis Generator 用法詳解

pswyjz發表於2021-09-09

MBG全部指代MyBatis Generator

  • 有4種執行MBG的方法,具體請看文件

  • MBG下載地址:

在MBG中,最主要也最重要的就是XML配置檔案,因此本文主要就是XML配置

這裡按照配置的順序對配置逐個講解,更細的內容可以配合中文文件參照。

1. 配置檔案頭

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "">

generatorConfiguration節點沒有任何屬性,直接寫節點即可,如下:

<generatorConfiguration>
    <!-- 具體配置內容 --></generatorConfiguration>

從這段開始,就是配置的主要內容,這些配置都是generatorConfiguration元素的子元素(有嚴格順序)

  1. (0個或1個)

  2. (0個或多個)

  3. (1個或多個)

元素

這個元素用來指定外部的屬性元素,不是必須的元素。

元素用於指定一個需要在配置中解析使用的外部屬性檔案,引入屬性檔案後,可以在配置中使用 ${property}這種形式的引用,透過這種方式引用屬性檔案中的屬性值。 對於後面需要配置的jdbc資訊targetProject屬性會很有用

這個屬性可以透過resource或者url來指定屬性檔案的位置,這兩個屬性只能使用其中一個來指定,同時出現會報錯

  • resource:指定classpath下的屬性檔案,使用類似com/myproject/generatorConfig.properties這樣的屬性值。

  • url:可以指定檔案系統上的特定位置,例如file:///C:/myfolder/generatorConfig.properties

元素

這個元素可以0或多個,不受限制。
最常見的用法是透過這個屬性指定驅動的路徑,例如:
<classPathEntry location="E:mysqlmysql-connector-java-5.1.29.jar"/>
注意,classPathEntry只在下面這兩種情況下才有效

  • 當載入 JDBC 驅動內省資料庫時

  • 當載入根類中的 JavaModelGenerator 檢查重寫的方法時

因此,如果你需要載入其他用途的jar包,classPathEntry起不到作用,不能這麼寫,解決的辦法就是將你用的jar包新增到類路徑中,在IDE中執行的時候,新增jar包比較容易。當從命令列執行的時候,需要用java -cp xx.jar,xx2.jar xxxMainClass這種方式在-cp後面指定來使用(注意-jar會導致-cp無效)。

元素

在MBG的配置中,至少需要有一個<context>元素。

<context>元素用於指定生成一組物件的環境。例如指定要連線的資料庫,要生成物件的型別和要處理的資料庫中的表。執行MBG的時候還可以指定要執行的<context>

該元素只有一個必選屬性id,用來唯一確定一個<context>元素,該id屬性可以在執行MBG時使用

此外還有幾個可選屬性

  • defaultModelType
    這個屬性很重要,這個屬性定義了MBG如何生成實體類
    這個屬性有以下可選值:

    • conditional:這是預設值,這個模型和下面的hierarchical類似,除了如果那個單獨的類將只包含一個欄位,將不會生成一個單獨的類。 因此,如果一個表的主鍵只有一個欄位,那麼不會為該欄位生成單獨的實體類,會將該欄位合併到基本實體類中。

    • flat:該模型為每一張表只生成一個實體類。這個實體類包含表中的所有欄位。這種模型最簡單,推薦使用。

    • hierarchical:如果表有主鍵,那麼該模型會產生一個單獨的主鍵實體類,如果表還有BLOB欄位, 則會為表生成一個包含所有BLOB欄位的單獨的實體類,然後為所有其他的欄位生成一個單獨的實體類。 MBG會在所有生成的實體類之間維護一個繼承關係。

  • targetRuntime:此屬性用於指定生成的程式碼的執行時環境。該屬性支援以下可選值:

    • MyBatis3:這是預設值

    • MyBatis3Simple

    • Ibatis2Java2

    • Ibatis2Java5 一般情況下使用預設值即可,有關這些值的具體作用以及區別請檢視中文文件的詳細內容。

  • introspectedColumnImpl:該引數可以指定擴充套件org.mybatis.generator.api.IntrospectedColumn該類的實現類。該屬性的作用可以檢視。

一般情況下,我們使用如下的配置即可:
<context id="Mysql" defaultModelType="flat">
如果你希望不生成和Example查詢有關的內容,那麼可以按照如下進行配置:
<context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
使用MyBatis3Simple可以避免在後面的<table>中逐個進行配置(後面會提到)
MBG配置中的其他幾個元素,基本上都是<context>的子元素,這些子元素(有嚴格的配置順序)包括:

  • (0個或多個)

  • (0個或多個)

  • (0個或1個)

  • (1個)

  • (0個或1個)

  • (1個)

  • (0個或1個)

  • (0個或1個)

  • (1個或多個)

其中<property>屬性比較特殊,後面講解的時候都會和父元素一起進行講解。在講解<property>屬性前,我們先看看什麼是分隔符?

這裡透過一個例子說明。假設在Mysql資料庫中有一個表名為user info,你沒有看錯,中間是一個空格,這種情況下如果寫出select * from user info這樣的語句,肯定是要報錯的,在Mysql中的時候我們一般會寫成如下的樣子:
select * from user info
這裡的使用的**反單引號()**就是**分隔符**,**分隔符**可以用於**表名**或者**列名**。 下面繼續看<property>`支援的屬性:

  • autoDelimitKeywords

  • beginningDelimiter

  • endingDelimiter

  • javaFileEncoding

  • javaFormatter

  • xmlFormatter

由於這些屬性比較重要,這裡一一講解。

首先是autoDelimitKeywords,當表名或者欄位名為SQL關鍵字的時候,可以設定該屬性為true,MBG會自動給表名或欄位名新增分隔符

然後這裡繼續上面的例子來講beginningDelimiterendingDelimiter屬性。
由於beginningDelimiterendingDelimiter的預設值為雙引號("),在Mysql中不能這麼寫,所以還要將這兩個預設值改為**反單引號()**,配置如下: <property name="beginningDelimiter" value=""/>
<property name="endingDelimiter" value=""/> 屬性javaFileEncoding`設定要使用的Java檔案的編碼,預設使用當前平臺的編碼,只有當生產的編碼需要特殊指定時才需要使用,一般用不到。

最後兩個javaFormatterxmlFormatter屬性可能會很有用,如果你想使用模板來定製生成的java檔案和xml檔案的樣式,你可以透過指定這兩個屬性的值來實現。

接下來分節對其他的子元素逐個進行介紹。

元素

該元素可以配置0個或者多個,不受限制。

<plugin>元素用來定義一個外掛。外掛用於擴充套件或修改透過MyBatis Generator (MBG)程式碼生成器生成的程式碼。

外掛將按在配置中配置的順序執行。

有關外掛的詳細資訊可以參考和了解更多。

元素

該元素最多可以配置1個。

這個元素非常有用,相信很多人都有過這樣的需求,就是希望MBG生成的程式碼中可以包含註釋資訊,具體就是生成表或欄位的備註資訊。

使用這個元素就能很簡單的實現我們想要的功能。這裡先介紹該元素,介紹完後會舉例如何擴充套件實現該功能。

該元素有一個可選屬性type,可以指定使用者的實現類,該類需要實現org.mybatis.generator.api.CommentGenerator介面。而且必有一個預設的構造方法。這個屬性接收預設的特殊值DEFAULT,會使用預設的實現類org.mybatis.generator.internal.DefaultCommentGenerator

預設的實現類中提供了兩個可選屬性,需要透過<property>屬性進行配置。

  • suppressAllComments:阻止生成註釋,預設為false

  • suppressDate:阻止生成的註釋包含時間戳,預設為false

一般情況下由於MBG生成的註釋資訊沒有任何價值,而且有時間戳的情況下每次生成的註釋都不一樣,使用版本控制的時候每次都會提交,因而一般情況下我們都會遮蔽註釋資訊,可以如下配置:
<commentGenerator>
<property name="suppressAllComments" value="true"/>
<property name="suppressDate" value="true"/>
</commentGenerator>

接下來我們簡單舉例實現生成包含表欄位註釋資訊的註釋

因為系統提供了一個預設的實現類,所以對我們來說,自己實現一個會很容易,最簡單的方法就是複製預設實現類程式碼到一個新的檔案中,修改類名如MyCommentGenerator,在你自己的實現類中,你可以選擇是否繼續支援上面的兩個屬性,你還可以增加對其他屬性的支援。

我們透過下面一個方法的修改來了解,其他幾個方法請自行修改@Override
public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
if (introspectedColumn.getRemarks() != null && !introspectedColumn.getRemarks().equals("")) {
field.addJavaDocLine("");
}
}
這個方法是給欄位新增註釋資訊的,其中IntrospectedColumn包含了欄位的完整資訊,透過getRemarks方法可以獲取欄位的註釋資訊。上面這個方法修改起來還是很容易的。除了欄位的註釋外還有GetterSetter,以及類的註釋。此外還有生成XML的註釋,大家可以根據預設的實現進行修改。

完成我們自己的實現類後,我們還需要做如下配置:

<pre style="margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; padding: 6px 10px; font-weight: 400; box-sizing: border-box; background-color: rgb(248, 248, 248); font-family: Menlo, "Liberation Mono", Consolas, "Courier New", "andale mono", "lucida console", monospace; font-size: 13px; line-height: 19px; color: rgb(0, 0, 0); word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgb(204, 204, 204); overflow: auto;"><commentGenerator type="com.github.abel533.mybatis.generator.MyCommentGenerator"/>
</pre>

元素

<jdbcConnection>用於指定資料庫連線資訊,該元素必選,並且只能有一個。

配置該元素只需要注意如果JDBC驅動不在classpath下,就需要透過<classPathEntry>元素引入jar包,這裡推薦將jar包放到classpath下。

該元素有兩個必選屬性:

  • driverClass:訪問資料庫的JDBC驅動程式的完全限定類名

  • connectionURL:訪問資料庫的JDBC連線URL

該元素還有兩個可選屬性:

  • userId:訪問資料庫的使用者ID

  • password:訪問資料庫的密碼

此外該元素還可以接受多個<property>子元素,這裡配置的<property>屬性都會新增到JDBC驅動的屬性中。

這個元素配置起來最容易,這裡舉個簡單例子:

<pre style="margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; padding: 6px 10px; font-weight: 400; box-sizing: border-box; background-color: rgb(248, 248, 248); font-family: Menlo, "Liberation Mono", Consolas, "Courier New", "andale mono", "lucida console", monospace; font-size: 13px; line-height: 19px; color: rgb(0, 0, 0); word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgb(204, 204, 204); overflow: auto;"><jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:"
userId="root"
password="">
</jdbcConnection>
</pre>

元素

該元素最多可以配置一個。

這個元素的配置用來指定JDBC型別和Java型別如何轉換。

該元素提供了一個可選的屬性type,和<commentGenerator>比較型別,提供了預設的實現DEFAULT,一般情況下使用預設即可,需要特殊處理的情況可以透過其他元素配置來解決,不建議修改該屬性。

該屬性還有一個可以配置的<property>元素。

可以配置的屬性為forceBigDecimals,該屬性可以控制是否強制DECIMALNUMERIC型別的欄位轉換為Java型別的java.math.BigDecimal,預設值為false,一般不需要配置。

預設情況下的轉換規則為:

  1. 如果精度>0或者長度>18,就會使用java.math.BigDecimal

  2. 如果精度=0並且10<=長度<=18,就會使用java.lang.Long

  3. 如果精度=0並且5<=長度<=9,就會使用java.lang.Integer

  4. 如果精度=0並且長度<5,就會使用java.lang.Short

如果設定為true,那麼一定會使用java.math.BigDecimal,配置示例如下:

<pre style="margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; padding: 6px 10px; font-weight: 400; box-sizing: border-box; background-color: rgb(248, 248, 248); font-family: Menlo, "Liberation Mono", Consolas, "Courier New", "andale mono", "lucida console", monospace; font-size: 13px; line-height: 19px; color: rgb(0, 0, 0); word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgb(204, 204, 204); overflow: auto;"><javaTypeResolver >
<property name="forceBigDecimals" value="true" />
</javaTypeResolver>
</pre>

元素

該元素必須配置一個,並且最多一個。

該元素用來控制生成的實體類,根據<context>中配置的defaultModelType,一個表可能會對應生成多個不同的實體類。一個表對應多個類實際上並不方便,所以前面也推薦使用flat,這種情況下一個表對應一個實體類。

該元素只有兩個屬性,都是必選的。

  • targetPackage:生成實體類存放的包名,一般就是放在該包下。實際還會受到其他配置的影響(<table>中會提到)。

  • targetProject:指定目標專案路徑,可以是絕對路徑或相對路徑(如 targetProject="src/main/java")。

該元素支援以下幾個<property>子元素屬性:

  • constructorBased:該屬性只對MyBatis3有效,如果true就會使用構造方法入參,如果false就會使用setter方式。預設為false

  • enableSubPackages:如果true,MBG會根據catalogschema來生成子包。如果false就會直接用targetPackage屬性。預設為false

  • immutable:該屬性用來配置實體類屬性是否可變,如果設定為true,那麼constructorBased不管設定成什麼,都會使用構造方法入參,並且不會生成setter方法。如果為false,實體類屬性就可以改變。預設為false

  • rootClass:設定所有實體類的基類。如果設定,需要使用類的全限定名稱。並且如果MBG能夠載入rootClass,那麼MBG不會覆蓋和父類中完全匹配的屬性。匹配規則:

    • 屬性名完全相同

    • 屬性型別相同

    • 屬性有getter方法

    • 屬性有setter方法

  • trimStrings:是否對資料庫查詢結果進行trim操作,如果設定為true就會生成類似這樣public void setUsername(String username) {this.username = username == null ? null : username.trim();}setter方法。預設值為false

配置示例如下:

<pre style="margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; padding: 6px 10px; font-weight: 400; box-sizing: border-box; background-color: rgb(248, 248, 248); font-family: Menlo, "Liberation Mono", Consolas, "Courier New", "andale mono", "lucida console", monospace; font-size: 13px; line-height: 19px; color: rgb(0, 0, 0); word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgb(204, 204, 204); overflow: auto;"><javaModelGenerator targetPackage="test.model" targetProject="srcmainjava">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator>
</pre>

元素

該元素可選,最多配置一個。但是有如下兩種必選的特殊情況:

  • 如果targetRuntime目標是iBATIS2,該元素必須配置一個。

  • 如果targetRuntime目標是MyBatis3,只有當<javaClientGenerator>需要XML時,該元素必須配置一個。 如果沒有配置<javaClientGenerator>,則使用以下的規則:

    • 如果指定了一個<sqlMapGenerator>,那麼MBG將只生成XML的SQL對映檔案和實體類。

    • 如果沒有指定<sqlMapGenerator>,那麼MBG將只生成實體類。

該元素只有兩個屬性(和前面提過的<javaModelGenerator>的屬性含義一樣),都是必選的。

  • targetPackage:生成實體類存放的包名,一般就是放在該包下。實際還會受到其他配置的影響(<table>中會提到)。

  • targetProject:指定目標專案路徑,可以是絕對路徑或相對路徑(如 targetProject="src/main/resources")。

該元素支援<property>子元素,只有一個可以配置的屬性:

  • enableSubPackages:如果true,MBG會根據catalogschema來生成子包。如果false就會直接用targetPackage屬性。預設為false

配置示例:

<pre style="margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; padding: 6px 10px; font-weight: 400; box-sizing: border-box; background-color: rgb(248, 248, 248); font-family: Menlo, "Liberation Mono", Consolas, "Courier New", "andale mono", "lucida console", monospace; font-size: 13px; line-height: 19px; color: rgb(0, 0, 0); word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgb(204, 204, 204); overflow: auto;"><sqlMapGenerator targetPackage="test.xml"  targetProject="srcmainresources">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
</pre>

元素

該元素可選,最多配置一個。

如果不配置該元素,就不會生成Mapper介面。

該元素有3個必選屬性:

  • type:該屬性用於選擇一個預定義的客戶端程式碼(可以理解為Mapper介面)生成器,使用者可以自定義實現,需要繼承org.mybatis.generator.codegen.AbstractJavaClientGenerator類,必選有一個預設的構造方法。 該屬性提供了以下預定的程式碼生成器,首先根據<context>targetRuntime分成三類:

    • IBATIS:生成的物件符合iBATIS的DAO框架(不建議使用)。

    • GENERIC-CI:生成的物件將只依賴於SqlMapClient,透過構造方法注入。

    • GENERIC-SI:生成的物件將只依賴於SqlMapClient,透過setter方法注入。

    • SPRING:生成的物件符合Spring的DAO介面

    • ANNOTATEDMAPPER:基於註解的Mapper介面,不會有對應的XML對映檔案

    • XMLMAPPER:所有的方法都在XML中,介面呼叫依賴XML檔案。

    • ANNOTATEDMAPPER:基於註解的Mapper介面,不會有對應的XML對映檔案

    • MIXEDMAPPER:XML和註解的混合形式,(上面這種情況中的)SqlProvider註解方法會被XML替代。

    • XMLMAPPER:所有的方法都在XML中,介面呼叫依賴XML檔案。

    • MyBatis3:

    • MyBatis3Simple:

    • Ibatis2Java2或Ibatis2Java5:

  • targetPackage:生成實體類存放的包名,一般就是放在該包下。實際還會受到其他配置的影響(<table>中會提到)。

  • targetProject:指定目標專案路徑,可以是絕對路徑或相對路徑(如 targetProject="src/main/java")。

該元素還有一個可選屬性:

  • implementationPackage:如果指定了該屬性,實現類就會生成在這個包中。

該元素支援<property>子元素設定的屬性:

  • enableSubPackages

  • exampleMethodVisibility

  • methodNameCalculator

  • rootInterface

  • useLegacyBuilder

這幾個屬性不太常用,具體作用請看完整的文件,這裡對rootInterface做個簡單介紹。

rootInterface用於指定一個所有生成的介面都繼承的父介面。 這個值可以透過<table>配置的rootInterface屬性覆蓋。

這個屬性對於通用Mapper來說,可以讓生成的所有介面都繼承該介面。

配置示例:

<pre style="margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; padding: 6px 10px; font-weight: 400; box-sizing: border-box; background-color: rgb(248, 248, 248); font-family: Menlo, "Liberation Mono", Consolas, "Courier New", "andale mono", "lucida console", monospace; font-size: 13px; line-height: 19px; color: rgb(0, 0, 0); word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgb(204, 204, 204); overflow: auto;"><javaClientGenerator type="XMLMAPPER" targetPackage="test.dao"
targetProject="srcmainjava"/>
</pre>

元素

該元素至少要配置一個,可以配置多個。

該元素用來配置要透過內省的表。只有配置的才會生成實體類和其他檔案。

該元素有一個必選屬性:

  • tableName:指定要生成的表名,可以使用匹配多個表。

例如要生成全部的表,可以按如下配置:

<pre style="margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; padding: 6px 10px; font-weight: 400; box-sizing: border-box; background-color: rgb(248, 248, 248); font-family: Menlo, "Liberation Mono", Consolas, "Courier New", "andale mono", "lucida console", monospace; font-size: 13px; line-height: 19px; color: rgb(0, 0, 0); word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgb(204, 204, 204); overflow: auto;"><table tableName="%" />
</pre>

該元素包含多個可選屬性:

  • schema:資料庫的schema,可以使用匹配。如果設定了該值,生成SQL的表名會變成如schema.tableName的形式。

  • catalog:資料庫的catalog,如果設定了該值,生成SQL的表名會變成如catalog.tableName的形式。

  • alias:如果指定,這個值會用在生成的select查詢SQL的表的別名和列名上。 列名會被別名為 alias_actualColumnName(別名_實際列名) 這種模式。

  • domainObjectName:生成物件的基本名稱。如果沒有指定,MBG會自動根據表名來生成名稱。

  • enableXXX:XXX代表多種SQL方法,該屬性用來指定是否生成對應的XXX語句。

  • selectByPrimaryKeyQueryId:DBA跟蹤工具會用到,具體請看詳細文件。

  • selectByExampleQueryId:DBA跟蹤工具會用到,具體請看詳細文件。

  • modelType:和<context>defaultModelType含義一樣,這裡可以針對表進行配置,這裡的配置會覆蓋<context>defaultModelType配置。

  • escapeWildcards:這個屬性表示當查詢列,是否對schema和表名中的SQL萬用字元 ('_' and '%') 進行轉義。 對於某些驅動當schema或表名中包含SQL萬用字元時(例如,一個表名是MY_TABLE,有一些驅動需要將下劃線進行轉義)是必須的。預設值是false

  • delimitIdentifiers:是否給識別符號增加分隔符。預設false。當catalog,schematableName中包含空白時,預設為true

  • delimitAllColumns:是否對所有列新增分隔符。預設false

該元素包含多個可用的<property>子元素,可選屬性為:

  • constructorBased:和<javaModelGenerator>中的屬性含義一樣。

  • ignoreQualifiersAtRuntime:生成的SQL中的表名將不會包含schemacatalog字首。

  • immutable:和<javaModelGenerator>中的屬性含義一樣。

  • modelOnly:此屬性用於配置是否為表只生成實體類。如果設定為true就不會有Mapper介面。如果配置了<sqlMapGenerator>,並且modelOnlytrue,那麼XML對映檔案中只有實體物件的對映元素(<resultMap>)。如果為true還會覆蓋屬性中的enableXXX方法,將不會生成任何CRUD方法。

  • rootClass:和<javaModelGenerator>中的屬性含義一樣。

  • rootInterface:和<javaClientGenerator>中的屬性含義一樣。

  • runtimeCatalog:執行時的catalog,當生成表和執行環境的表的catalog不一樣的時候可以使用該屬性進行配置。

  • runtimeSchema:執行時的schema,當生成表和執行環境的表的schema不一樣的時候可以使用該屬性進行配置。

  • runtimeTableName:執行時的tableName,當生成表和執行環境的表的tableName不一樣的時候可以使用該屬性進行配置。

  • selectAllOrderByClause:該屬性值會追加到selectAll方法後的SQL中,會直接跟order by拼接後新增到SQL末尾。

  • useActualColumnNames:如果設定為true,那麼MBG會使用從資料庫後設資料獲取的列名作為生成的實體物件的屬性。 如果為false(預設值),MGB將會嘗試將返回的名稱轉換為駝峰形式。 在這兩種情況下,可以透過 元素顯示指定,在這種情況下將會忽略這個(useActualColumnNames)屬性。

  • useColumnIndexes:如果是true,MBG生成resultMaps的時候會使用列的索引,而不是結果中列名的順序。

  • useCompoundPropertyNames:如果是true,那麼MBG生成屬性名的時候會將列名和列備註接起來. 這對於那些透過第四代語言自動生成列(例如:FLD22237),但是備註包含有用資訊(例如:"customer id")的資料庫來說很有用. 在這種情況下,MBG會生成屬性名FLD2237_CustomerId。

除了<property>子元素外,<table>還包含以下子元素:

  • (0個或1個)

  • (0個或1個)

  • (0個或多個)

  • (0個或多個)

下面對這4個元素進行詳細講解。

  1. 元素

這個元素最多可以配置一個。
這個元素用來指定自動生成主鍵的屬性(identity欄位或者sequences序列)。如果指定這個元素,MBG在生成insert的SQL對映檔案中插入一個<selectKey>元素。 這個元素非常重要,這個元素包含下面兩個必選屬性:

  • column:生成列的列名。

  • sqlStatement:將返回新值的 SQL 語句。如果這是一個identity列,您可以使用其中一個預定義的的特殊值。預定義值如下:

    • Cloudscape

    • DB2

    • DB2_MF

    • Derby

    • HSQLDB

    • Informix

    • MySql

    • SqlServer

    • SYBASE

    • JDBC:這會配置MBG使用MyBatis3支援的JDBC標準的生成key來生成程式碼。 這是一個獨立於資料庫獲取標識列中的值的方法。 重要: 只有當目標執行為MyBatis3時才會產生正確的程式碼。 如果與iBATIS2一起使用目標執行時會產生執行時錯誤的程式碼。

這個元素還包含兩個可選屬性:

  • identity:當設定為true時,該列會被標記為identity列, 並且<selectKey>元素會被插入在insert後面。 當設定為false時,<selectKey>會插入到insert之前(通常是序列)。重要: 即使您type屬性指定為post,您仍然需要為identity列將該引數設定為true。 這將標誌MBG從插入列表中刪除該列。預設值是false

  • type:type=post and identity=true的時候生成的<selectKey>中的order=AFTER,當type=pre的時候,identity只能為false,生成的<selectKey>中的order=BEFORE。可以這麼理解,自動增長的列只有插入到資料庫後才能得到ID,所以是AFTER,使用序列時,只有先獲取序列之後,才能插入資料庫,所以是BEFORE

配置示例一:

<pre style="margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; padding: 6px 10px; font-weight: 400; box-sizing: border-box; background-color: rgb(248, 248, 248); font-family: Menlo, "Liberation Mono", Consolas, "Courier New", "andale mono", "lucida console", monospace; font-size: 13px; line-height: 19px; color: rgb(0, 0, 0); word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgb(204, 204, 204); overflow: auto;"><table tableName="user login info" domainObjectName="UserLoginInfo">
<generatedKey column="id" sqlStatement="Mysql"/>
</table>
</pre>

對應的生成的結果:

<pre style="margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; padding: 6px 10px; font-weight: 400; box-sizing: border-box; background-color: rgb(248, 248, 248); font-family: Menlo, "Liberation Mono", Consolas, "Courier New", "andale mono", "lucida console", monospace; font-size: 13px; line-height: 19px; color: rgb(0, 0, 0); word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgb(204, 204, 204); overflow: auto;"><insert id="insert" parameterType="test.model.UserLoginInfo">
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into user login info (Id, username, logindate, loginip)
values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{logindate,jdbcType=TIMESTAMP}, #{loginip,jdbcType=VARCHAR})
</insert>
</pre>

配置示例二:

<pre style="margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; padding: 6px 10px; font-weight: 400; box-sizing: border-box; background-color: rgb(248, 248, 248); font-family: Menlo, "Liberation Mono", Consolas, "Courier New", "andale mono", "lucida console", monospace; font-size: 13px; line-height: 19px; color: rgb(0, 0, 0); word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgb(204, 204, 204); overflow: auto;"><table tableName="user login info" domainObjectName="UserLoginInfo">
<generatedKey column="id" sqlStatement="select SEQ_ID.nextval from dual"/>
</table>
</pre>

對應的生成結果:

<pre style="margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; padding: 6px 10px; font-weight: 400; box-sizing: border-box; background-color: rgb(248, 248, 248); font-family: Menlo, "Liberation Mono", Consolas, "Courier New", "andale mono", "lucida console", monospace; font-size: 13px; line-height: 19px; color: rgb(0, 0, 0); word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgb(204, 204, 204); overflow: auto;"><insert id="insert" parameterType="test.model.UserLoginInfo">
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.Integer">
select SEQ_ID.nextval from dual
</selectKey>
insert into user login info (Id, username, logindate, loginip)
values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{logindate,jdbcType=TIMESTAMP},#{loginip,jdbcType=VARCHAR})
</insert>
</pre>

  1. 元素

該元素最多可以配置一個,使用該元素可以在生成列之前,對列進行重新命名。這對那些存在同一字首的欄位想在生成屬性名時去除字首的表非常有用。 例如假設一個表包含以下的列:

  • CUST_BUSINESS_NAME

  • CUST_STREET_ADDRESS

  • CUST_CITY

  • CUST_STATE

生成的所有屬性名中如果都包含CUST的字首可能會讓人不爽。這些字首可以透過如下方式定義重新命名規則:

<pre style="margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; padding: 6px 10px; font-weight: 400; box-sizing: border-box; background-color: rgb(248, 248, 248); font-family: Menlo, "Liberation Mono", Consolas, "Courier New", "andale mono", "lucida console", monospace; font-size: 13px; line-height: 19px; color: rgb(0, 0, 0); word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgb(204, 204, 204); overflow: auto;"><columnRenamingRule searchString="^CUST_" replaceString="" />
</pre>

注意,在內部,MBG使用java.util.regex.Matcher.replaceAll方法實現這個功能。 請參閱有關該方法的文件和在Java中使用正規表示式的例子。

<columnOverride>匹配一列時,這個元素(<columnRenamingRule>)會被忽略。<columnOverride>優先於重新命名的規則。

該元素有一個必選屬性:

  • searchString:定義將被替換的字串的正規表示式。

該元素有一個可選屬性:

  • replaceString:這是一個用來替換搜尋字串列每一個匹配項的字串。如果沒有指定,就會使用空字串。

關於<table><property>屬性useActualColumnNames對此的影響可以檢視完整文件。

  1. 元素

該元素可選,可以配置多個。

該元素從將某些屬性預設計算的值更改為指定的值。

該元素有一個必選屬性:

  • column:要重寫的列名。

該元素有多個可選屬性:

  • property:要使用的Java屬性的名稱。如果沒有指定,MBG會根據列名生成。 例如,如果一個表的一列名為STRT_DTE,MBG會根據<table>useActualColumnNames屬性生成STRT_DTEstrtDte

  • javaType:該列屬性值為完全限定的Java型別。如果需要,這可以覆蓋由JavaTypeResolver計算出的型別。 對某些資料庫來說,這是必要的用來處理“奇怪的”資料庫型別(例如MySql的unsigned bigint型別需要對映為java.lang.Object)。

  • jdbcType:該列的JDBC型別(INTEGER, DECIMAL, NUMERIC, VARCHAR等等)。 如果需要,這可以覆蓋由JavaTypeResolver計算出的型別。 對某些資料庫來說,這是必要的用來處理怪異的JDBC驅動 (例如DB2的LONGVARCHAR型別需要為iBATIS 對映為VARCHAR)。

  • typeHandler:使用者定義的需要用來處理這列的型別處理器。它必須是一個繼承iBATIS的TypeHandler類或TypeHandlerCallback介面(該介面很容易繼承)的全限定的類名。如果沒有指定或者是空白,iBATIS會用預設的型別處理器來處理型別。重要:MBG不會校驗這個型別處理器是否存在或者可用。 MGB只是簡單的將這個值插入到生成的SQL對映的配置檔案中。

  • delimitedColumnName:指定是否應在生成的SQL的列名稱上增加分隔符。 如果列的名稱中包含空格,MGB會自動新增分隔符, 所以這個重寫只有當列名需要強制為一個合適的名字或者列名是資料庫中的保留字時是必要的。

配置示例:

<pre style="margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; padding: 6px 10px; font-weight: 400; box-sizing: border-box; background-color: rgb(248, 248, 248); font-family: Menlo, "Liberation Mono", Consolas, "Courier New", "andale mono", "lucida console", monospace; font-size: 13px; line-height: 19px; color: rgb(0, 0, 0); word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgb(204, 204, 204); overflow: auto;"><table schema="DB2ADMIN" tableName="ALLTYPES" >
<columnOverride column="LONG_VARCHAR_FIELD" javaType="java.lang.String" jdbcType="VARCHAR" />
</table>
</pre>

  1. 元素

該元素可選,可以配置多個。

該元素可以用來遮蔽不需要生成的列。

該元素有一個必選屬性:

  • column:要忽略的列名。

該元素還有一個可選屬性:

  • delimitedColumnName:匹配列名的時候是否區分大小寫。如果為true則區分。預設值為false,不區分大小寫。

本節內容針對MyBatis3,使用iBATIS的不一定適用。

以下根據個人經驗(對此有意見的可以留言)對一些配置看法列出如下幾點:

  1. 關於實體類的modelType,建議使用defaultModelType="flat",只有一個物件的情況下管理畢竟方便,使用也簡單。

  2. 關於註釋<commentGenerator>,不管你是否要重寫自己的註釋生成器,有一點不能忘記,那就是註釋中一定要保留@mbggenerated,MBG透過該字串來判斷程式碼是否為程式碼生成器生成的程式碼,有該標記的的程式碼在重新生成的時候會被刪除,不會重複。不會在XML中出現重複元素。

  3. 使用MBG生成的程式碼時,建議儘可能不要去修改自動生成的程式碼,而且要生成帶有@mbggenerated,這樣才不會在每次重新生成程式碼的時候需要手動修改好多內容。

  4. 仍然是註釋相關,在<commentGenerator>中,建議一定要保留suppressAllComments屬性(使用預設值false),一定要取消(設為true)時間戳suppressDate,避免重複提交SVN。

  5. <jdbcConnection>建議將JDBC驅動放到專案的classpath下,而不是使用<classPathEntry>來引入jar包,主要考慮到所有開發人員的統一性。

  6. 當資料庫欄位使用CHAR時,建議在<javaModelGenerator>中設定<property name="trimStrings" value="true" />,可以自動去掉不必要的空格。

  7. <javaClientGenerator>中,建議設定type="XMLMAPPER",不建議使用註解或混合模式,比較程式碼和SQL完全分離易於維護。

  8. 建議儘可能在<table>中配置<generatedKey>,避免手工操作,以便於MBG重複執行程式碼生成。

如果有其他有價值的經驗,會繼續補充。

綜合以上資訊,這裡給出一個Mysql的簡單配置:

<pre style="margin-top: 0px !important; margin-right: 0px; margin-bottom: 0px !important; margin-left: 0px; padding: 6px 10px; font-weight: 400; box-sizing: border-box; background-color: rgb(248, 248, 248); font-family: Menlo, "Liberation Mono", Consolas, "Courier New", "andale mono", "lucida console", monospace; font-size: 13px; line-height: 19px; color: rgb(0, 0, 0); word-break: break-all; word-wrap: break-word; white-space: pre-wrap; border: 1px solid rgb(204, 204, 204); overflow: auto;"><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"">

<generatorConfiguration>
<context id="MysqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
<property name="beginningDelimiter" value=""/> <property name="endingDelimiter" value=""/>

    <commentGenerator>
        <property name="suppressDate" value="true"/>
    </commentGenerator>

    <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                    connectionURL="jdbc:mysql://localhost:3306/test"
                    userId="root"
                    password="">
    </jdbcConnection>

    <javaModelGenerator targetPackage="test.model" targetProject="srcmainjava">
        <property name="trimStrings" value="true" />
    </javaModelGenerator>

    <sqlMapGenerator targetPackage="test.xml"  targetProject="srcmainresources"/>

    <javaClientGenerator type="XMLMAPPER" targetPackage="test.dao"  targetProject="srcmainjava"/>

    <table tableName="%">
        <generatedKey column="id" sqlStatement="Mysql"/>
    </table></context>

</generatorConfiguration>
</pre>

<table>這裡用的萬用字元匹配全部的表,另外所有表都有自動增長的id欄位。如果不是所有表的配置都一樣,可以做針對性的配置。

改動:去掉來不建議使用Example查詢的建議,Example在單表操作上優勢明顯,可以看個人情況使用。



作者:芥末無疆sss
連結:
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/755/viewspace-2816169/,如需轉載,請註明出處,否則將追究法律責任。

相關文章