在《第一個(gè)MyBatis程序》一節(jié)中,我們編寫了 MyBatis 的配置文件 mybatis-config.xml,在該文件中,您可以配置各種元素。
MyBatis 配置文件的結(jié)構(gòu)如下。
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><!-- 配置 --> <properties /><!-- 屬性 --> <settings /><!-- 設(shè)置 --> <typeAliases /><!-- 類型命名 --> <typeHandlers /><!-- 類型處理器 --> <objectFactory /><!-- 對(duì)象工廠 --> <plugins /><!-- 插件 --> <environments><!-- 配置環(huán)境 --> <environment><!-- 環(huán)境變量 --> <transactionManager /><!-- 事務(wù)管理器 --> <dataSource /><!-- 數(shù)據(jù)源 --> </environment> </environments> <databaseIdProvider /><!-- 數(shù)據(jù)庫(kù)廠商標(biāo)識(shí) --> <mappers /><!-- 映射器 --> </configuration>
mybatis-config.xml 文件中的元素節(jié)點(diǎn)是有一定順序的,節(jié)點(diǎn)位置必須按以上位置排序,否則會(huì)編譯錯(cuò)誤。
下面介紹 XML 配置文件中的重要元素(標(biāo)簽)。
configuration 元素是整個(gè) XML 配置文件的根節(jié)點(diǎn),其角色就相當(dāng)于是 MyBatis 的總管,MyBatis 所有的配置信息都會(huì)存放在它里面。
properties 標(biāo)簽可以通過(guò) resource 屬性指定外部 properties 文件(database.properties),也可以通過(guò) properties 子元素配置。
使用 properties 指定外部文件,代碼如下。
<properties resource="mybatisDemo/resources/database.properties"/>
database.properties 用于描述數(shù)據(jù)庫(kù)連接的相關(guān)配置,例如數(shù)據(jù)庫(kù)驅(qū)動(dòng)、連接數(shù)據(jù)庫(kù)的 url、數(shù)據(jù)庫(kù)用戶名、數(shù)據(jù)庫(kù)密碼等。
通過(guò) properties 子元素 property 配置 username 和 password 變量,然后在 environments 節(jié)點(diǎn)中引用這些變量,代碼如下。
<properties> <property name="username" value="root"/> <property name="password" value="root"/> </properties>
在 environments 節(jié)點(diǎn)中引用 username 和 password 變量。
<environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments>
也可以不使用 properties 標(biāo)簽,直接將屬性值寫在 value 中。
settings 標(biāo)簽用于配置 MyBatis 的運(yùn)行時(shí)行為,它能深刻的影響 MyBatis 的底層運(yùn)行,一般不需要大量配置,大部分情況下使用其默認(rèn)值即可。
settings 的配置項(xiàng)很多,但是真正用到的不會(huì)太多,我們把常用的配置項(xiàng)研究清楚就可以了。settings 配置項(xiàng)說(shuō)明如下表所示(表中紅色字體的配置項(xiàng)為常用配置項(xiàng))。
settings 配置項(xiàng)說(shuō)明
配置項(xiàng) | 作用 | 配置選項(xiàng) | 默認(rèn)值 |
---|---|---|---|
cacheEnabled | 該配置影響所有映射器中配置緩存的全局開關(guān) | true|false | true |
lazyLoadingEnabled | 延遲加載的全局開關(guān)。當(dāng)開啟時(shí),所有關(guān)聯(lián)對(duì)象都會(huì)延遲加載。在特定關(guān)聯(lián)關(guān)系中可通過(guò)設(shè)置 fetchType 屬性來(lái)覆蓋該項(xiàng)的開關(guān)狀態(tài) | true|false | false |
aggressiveLazyLoading | 當(dāng)啟用時(shí),對(duì)任意延遲屬性的調(diào)用會(huì)使帶有延遲加載屬性的對(duì)象完整加載;反之,每種屬性將會(huì)按需加載 | true|false | 版本3.4.1(不包含) 之前默認(rèn)值為true, 之后為false |
multipleResultSetsEnabled | 是否允許單一語(yǔ)句返回多結(jié)果集(需要兼容驅(qū)動(dòng)) | true|false | true |
useColumnLabel | 使用列標(biāo)簽代替列名。不同的驅(qū)動(dòng)會(huì)有不同的表現(xiàn),具體可參考相關(guān)驅(qū)動(dòng)文檔或通過(guò)測(cè)試這兩種不同的模式來(lái)觀察所用驅(qū)動(dòng)的結(jié)果 | true|false | true |
useGeneratedKeys | 允許JDBC 支持自動(dòng)生成主鍵,需要驅(qū)動(dòng)兼容。如果設(shè)置為 true,則這個(gè)設(shè)置強(qiáng)制使用自動(dòng)生成主鍵,盡管一些驅(qū)動(dòng)不能兼容但仍可正常工作(比如 Derby) | true|false | false |
autoMappingBehavior | 指定 MyBatis 應(yīng)如何自動(dòng)映射列到字段或?qū)傩浴?NONE 表示取消自動(dòng)映射。 PARTIAL 表示只會(huì)自動(dòng)映射,沒(méi)有定義嵌套結(jié)果集和映射結(jié)果集。 FULL 會(huì)自動(dòng)映射任意復(fù)雜的結(jié)果集(無(wú)論是否嵌套) | NONE、PARTIAL、FULL | PARTIAL |
autoMappingUnkno wnColumnBehavior | 指定自動(dòng)映射當(dāng)中未知列(或未知屬性類型)時(shí)的行為。 默認(rèn)是不處理,只有當(dāng)日志級(jí)別達(dá)到 WARN 級(jí)別或者以下,才會(huì)顯示相關(guān)日志,如果處理失敗會(huì)拋出 SqlSessionException 異常 | NONE、WARNING、FAILING | NONE |
defaultExecutorType | 配置默認(rèn)的執(zhí)行器。SIMPLE 是普通的執(zhí)行器;REUSE 會(huì)重用預(yù)處理語(yǔ)句(prepared statements);BATCH 執(zhí)行器將重用語(yǔ)句并執(zhí)行批量更新 | SIMPLE、REUSE、BATCH | SIMPLE |
defaultStatementTimeout | 設(shè)置超時(shí)時(shí)間,它決定驅(qū)動(dòng)等待數(shù)據(jù)庫(kù)響應(yīng)的秒數(shù) | 任何正整數(shù) | Not Set (null) |
defaultFetchSize | 設(shè)置數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序默認(rèn)返回的條數(shù)限制,此參數(shù)可以重新設(shè)置 | 任何正整數(shù) | Not Set (null) |
safeRowBoundsEnabled | 允許在嵌套語(yǔ)句中使用分頁(yè)(RowBounds)。如果允許,設(shè)置 false | true|false | false |
safeResultHandlerEnabled | 允許在嵌套語(yǔ)句中使用分頁(yè)(ResultHandler)。如果允許,設(shè)置false | true|false | true |
mapUnderscoreToCamelCase | 是否開啟自動(dòng)駝峰命名規(guī)則映射,即從經(jīng)典數(shù)據(jù)庫(kù)列名 A_COLUMN 到經(jīng)典 Java 屬性名 aColumn 的類似映射 | true|false | false |
localCacheScope | MyBatis 利用本地緩存機(jī)制(Local Cache)防止循環(huán)引用(circular references)和加速聯(lián)復(fù)嵌套査詢。 默認(rèn)值為 SESSION,這種情況下會(huì)緩存一個(gè)會(huì)話中執(zhí)行的所有查詢。若設(shè)置值為 STATEMENT,本地會(huì)話僅用在語(yǔ)句執(zhí)行上,對(duì)相同 SqlScssion 的不同調(diào)用將不會(huì)共享數(shù)據(jù) | SESSION|STATEMENT | SESSION |
jdbcTypeForNull | 當(dāng)沒(méi)有為參數(shù)提供特定的 JDBC 類型時(shí),為空值指定 JDBC 類型。某些驅(qū)動(dòng)需要指定列的 JDBC 類型,多數(shù)情況直接用一般類型即可,比如 NULL、VARCHAR 或 OTHER | NULL、VARCHAR、OTHER | OTHER |
lazyLoadTriggerMethods | 指定哪個(gè)對(duì)象的方法觸發(fā)一次延遲加載 | — | equals、clone、hashCode、toString |
defaultScriptingLanguage | 指定動(dòng)態(tài) SQL 生成的默認(rèn)語(yǔ)言 | — | org.apache.ibatis .script.ing.xmltags .XMLDynamicLanguageDriver |
callSettersOnNulls | 指定當(dāng)結(jié)果集中值為 null 時(shí),是否調(diào)用映射對(duì)象的 setter(map 對(duì)象時(shí)為 put)方法,這對(duì)于 Map.kcySet() 依賴或 null 值初始化時(shí)是有用的。注意,基本類型(int、boolean 等)不能設(shè)置成 null | true|false | false |
logPrefix | 指定 MyBatis 增加到日志名稱的前綴 | 任何字符串 | Not set |
loglmpl | 指定 MyBatis 所用日志的具體實(shí)現(xiàn),未指定時(shí)將自動(dòng)?xùn)苏?/td> | SLF4J|LOG4J|LOG4J2| JDK_LOGGING| COMMONS_LOGGING| ST DOUT_LOGGING| NO_LOGGING | Not set |
proxyFactory | 指定 MyBatis 創(chuàng)建具有延遲加栽能力的對(duì)象所用到的代理工具 | CGLIB|JAVASSIST | JAVASSIST (MyBatis 版本為 3.3 及以上的) |
vfsImpl | 指定 VFS 的實(shí)現(xiàn)類 | 提供 VFS 類的全限定名,如果存在多個(gè),可以使用逗號(hào)分隔 | Not set |
useActualParamName | 允許用方法參數(shù)中聲明的實(shí)際名稱引用參數(shù)。要使用此功能,項(xiàng)目必須被編譯為 Java 8 參數(shù)的選擇。(從版本 3.4.1 開始可以使用) | true|false | true |
下面給出一個(gè)全量的配置樣例,如下所示。
<settings> <setting name="cacheEnabled" value="true"/> <setting name="lazyLoadingEnabled" value="true"/> <setting name="multipleResultSetsEnabled" value="true"/> <setting name="useColumnLabel" value="true"/> <setting name="useGeneratedKeys" value="false"/> <setting name="autoMappingBehavior" value="PARTIAL"/> <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/> <setting name="defaultExecutorType" value="SIMPLE"/> <setting name="defaultStatementTimeout" value="25"/> <setting name="defaultFetchSize" value="100"/> <setting name="safeRowBoundsEnabled" value="false"/> <setting name="mapUnderscoreToCamelCase" value="false"/> <setting name="localCacheScope" value="SESSION"/> <setting name="jdbcTypeForNull" value="OTHER"/> <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/> </settings>
為了不在任何地方都指定類的全限定名,我們可以使用 typeAliases 標(biāo)簽定義一個(gè)別名。
例如,在 net.bianchengbang.po 包中有一個(gè) Student 類,則該類的全限定名稱為 net.bianchengbang.po.Student。使用 typeAliases 標(biāo)簽定義別名,這樣就不用每次都書寫類的全限定名稱了,代碼如下。
<typeAliases> <typeAlias alias = "Student" type = "net.bianchengbang.po.Student"/> </typeAliases>
如果需要對(duì)同一個(gè)包下的多個(gè)類定義別名,則可以定義為:
<typeAliases> <package name="net.biancheng.po"/> </typeAliases>
這樣 MyBatis 將掃描 net.biancheng.po 包里面的類,將其第一個(gè)字母變?yōu)樾懽鳛槠鋭e名,例如 Student 別名為 student,User 別名為 user。
typeHandlers 主要將獲取的值合理地轉(zhuǎn)化為 Java 類型。在 typeHandler 中,分為 jdbcType 和 javaType,其中 jdbcType 用于定義數(shù)據(jù)庫(kù)類型,而 javaType 用于定義 Java 類型,typeHandler 的作用就是承擔(dān) jdbcType 和 javaType 之間的相互轉(zhuǎn)換。
MyBatis 支持自定義處理類型,在自定義處理類型時(shí),需要實(shí)現(xiàn) org.apache.ibatis.type.TypeHandler 接口或繼承 org.apache.ibatis.type.BaseTypeHandle 類。詳細(xì)可參考官網(wǎng):http://www.mybatis.org/mybatis-3/zh/configuration.html#typeHandlers
在 environments 標(biāo)簽中,可以配置 MyBatis 的多套運(yùn)行環(huán)境,將 SQL 映射到多個(gè)不同的數(shù)據(jù)庫(kù)上。
environment 是 environments 的子標(biāo)簽,用來(lái)配置 MyBatis 的一套運(yùn)行環(huán)境,需指定運(yùn)行環(huán)境 ID、事務(wù)管理、數(shù)據(jù)源配置等相關(guān)信息。
我們可以通過(guò)配置多個(gè) environment 標(biāo)簽來(lái)連接多個(gè)數(shù)據(jù)庫(kù),需要注意的是必須指定其中一個(gè)為默認(rèn)運(yùn)行環(huán)境(通過(guò)default指定)。
environment 標(biāo)簽提供了兩個(gè)子標(biāo)簽,即 transactionManager 和 dataSource。
MyBatis 支持兩個(gè)事務(wù)管理器,即 JDBC 和 MANAGED。
如果使用 JDBC 類型的事務(wù)管理器,則應(yīng)用程序服務(wù)器負(fù)責(zé)事務(wù)管理操作,例如提交、回滾等。如果使用 MANAGED 類型的事務(wù)管理器,則應(yīng)用程序服務(wù)器負(fù)責(zé)管理連接生命周期。
用于配置數(shù)據(jù)庫(kù)的連接屬性,例如要連接的數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序名稱、URL、用戶名和密碼等。
dataSource 中的 type 屬性用于指定數(shù)據(jù)源類型,有以下 3 種類型。
UNPOOLED 沒(méi)有數(shù)據(jù)庫(kù)連接池,效率低下。MyBatis 需要打開和關(guān)閉每個(gè)數(shù)據(jù)庫(kù)操作的連接,它有點(diǎn)慢,通常應(yīng)用于簡(jiǎn)單的應(yīng)用程序。
對(duì)于 POOLED 數(shù)據(jù)源類型,MyBatis 將維護(hù)一個(gè)數(shù)據(jù)庫(kù)連接池。并且對(duì)于每個(gè)數(shù)據(jù)庫(kù)的操作,MyBatis 都會(huì)使用連接池中的連接,并在操作完成后將它們返回到池中。減少了創(chuàng)建新連接所需的初始連接和身份驗(yàn)證時(shí)間。
對(duì)于 JNDI 的數(shù)據(jù)源類型,MyBatis 將從 JNDI 數(shù)據(jù)源中獲取連接。
dataSource 標(biāo)簽示例代碼如下:
<dataSource type="POOLED"> <!-- MySQL數(shù)據(jù)庫(kù)驅(qū)動(dòng) --> <property name="driver" value="com.mysql.jdbc.Driver" /> <!-- 連接數(shù)據(jù)庫(kù)的URL --> <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf8" /> <property name="username" value="root" /> <property name="password" value="root" /> </dataSource>
mappers 標(biāo)簽用于指定 MyBatis SQL 映射文件的路徑。
mapper 是 mappers 的子標(biāo)簽,mapper 中的 resource 屬性用于指定 SQL 映射文件的路徑(類資源路徑)
例如,SQL 映射文件的名稱是 Student.xml,它位于名為 net.biancheng.mapper 的包中,那么您可以這樣配置:
<mappers> <mapper resource="net/biancheng/mapper/Student.xml"/> </mappers>