Mybatis配置解析
配置
MyBatis 的配置文件包含了會深深影響 MyBatis 行為的設置和屬性資訊。 配置文檔的頂層結構如下:
- configuration(配置)
- properties(屬性)
- settings(設置)
- typeAliases(類型別名)
- typeHandlers(類型處理器)
- objectFactory(對象工廠)
- plugins(插件)
- environments(環境配置)
- environment(環境變數)
- transactionManager(事務管理器)
- dataSource(數據源)
- environment(環境變數)
- databaseIdProvider(資料庫廠商標識)
- mappers(映射器)
注意配置順序
紅線報錯:
The content of element type "configuration" must match
(properties?,
settings?,
typeAliases?,
typeHandlers?,
objectFactory?,
objectWrapperFactory?,
reflectorFactory?,
plugins?,
environments?,
databaseIdProvider?,
mappers?).
屬性(properties)
這些屬性可以在外部進行配置,並可以進行動態替換。你既可以在典型的 Java 屬性文件中配置這些屬性,也可以在 properties 元素的子元素中設置。例如:
<properties resource="org/mybatis/example/config.properties">
<property name="username" value="dev_user"/>
<property name="password" value="F2Fa3!33TYyg"/>
</properties>
如果兩個文件使用同一個欄位,優先使用外部配置文件
設置好的屬性可以在整個配置文件中用來替換需要動態配置的屬性值。比如:
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
環境配置(environments)
MyBatis 可以配置成適應多種環境,這種機制有助於將 SQL 映射應用於多種資料庫之中, 現實情況下有多種理由需要這麼做。
不過要記住:儘管可以配置多個環境,但每個 SqlSessionFactory 實例只能選擇一種環境。
所以,如果你想連接兩個資料庫,就需要創建兩個 SqlSessionFactory 實例,每個資料庫對應一個。而如果是三個資料庫,就需要三個實例,依此類推,記起來很簡單:
- 每個資料庫對應一個 SqlSessionFactory 實例
為了指定創建哪種環境,只要將它作為可選的參數傳遞給 SqlSessionFactoryBuilder 即可。可以接受環境配置的兩個方法簽名是:
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties);
如果忽略了環境參數,那麼將會載入默認環境,如下所示:
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, properties);
environments 元素定義了如何配置環境。
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="..." value="..."/>
</transactionManager>
<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>
注意一些關鍵點:
- 默認使用的環境 ID(比如:default=”development”)。
- 每個 environment 元素定義的環境 ID(比如:id=”development”)。
- 事務管理器的配置(比如:type=”JDBC”)。
- 數據源的配置(比如:type=”POOLED”)。
默認環境和環境 ID 顧名思義。 環境可以隨意命名,但務必保證默認的環境 ID 要匹配其中一個環境 ID。
事務管理器(transactionManager)
在 MyBatis 中有兩種類型的事務管理器(也就是 type=”[JDBC|MANAGED]”):
-
JDBC – 這個配置直接使用了 JDBC 的提交和回滾設施,它依賴從數據源獲得的連接來管理事務作用域。
-
MANAGED – 這個配置幾乎沒做什麼。它從不提交或回滾一個連接,而是讓容器來管理事務的整個生命周期(比如 JEE 應用伺服器的上下文)。 默認情況下它會關閉連接。然而一些容器並不希望連接被關閉,因此需要將 closeConnection 屬性設置為 false 來阻止默認的關閉行為。例如:
<transactionManager type="MANAGED"> <property name="closeConnection" value="false"/> </transactionManager>
提示 如果你正在使用 Spring + MyBatis,則沒有必要配置事務管理器,因為 Spring 模組會使用自帶的管理器來覆蓋前面的配置。
這兩種事務管理器類型都不需要設置任何屬性。它們其實是類型別名,換句話說,你可以用 TransactionFactory 介面實現類的全限定名或類型別名代替它們。
public interface TransactionFactory {
default void setProperties(Properties props) { // 從 3.5.2 開始,該方法為默認方法
// 空實現
}
Transaction newTransaction(Connection conn);
Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);
}
在事務管理器實例化後,所有在 XML 中配置的屬性將會被傳遞給 setProperties() 方法。你的實現還需要創建一個 Transaction 介面的實現類,這個介面也很簡單:
public interface Transaction {
Connection getConnection() throws SQLException;
void commit() throws SQLException;
void rollback() throws SQLException;
void close() throws SQLException;
Integer getTimeout() throws SQLException;
}
使用這兩個介面,你可以完全自定義 MyBatis 對事務的處理。
數據源(dataSource)
dataSource 元素使用標準的 JDBC 數據源介面來配置 JDBC 連接對象的資源。
- 大多數 MyBatis 應用程式會按示例中的例子來配置數據源。雖然數據源配置是可選的,但如果要啟用延遲載入特性,就必須配置數據源。
有三種內建的數據源類型(也就是 type=”[UNPOOLED|POOLED|JNDI]”):
UNPOOLED– 這個數據源的實現會每次請求時打開和關閉連接。雖然有點慢,但對那些資料庫連接可用性要求不高的簡單應用程式來說,是一個很好的選擇。 性能表現則依賴於使用的資料庫,對某些資料庫來說,使用連接池並不重要,這個配置就很適合這種情形。UNPOOLED 類型的數據源僅僅需要配置以下 5 種屬性:
driver
– 這是 JDBC 驅動的 Java 類全限定名(並不是 JDBC 驅動中可能包含的數據源類)。url
– 這是資料庫的 JDBC URL 地址。username
– 登錄資料庫的用戶名。password
– 登錄資料庫的密碼。defaultTransactionIsolationLevel
– 默認的連接事務隔離級別。defaultNetworkTimeout
– 等待資料庫操作完成的默認網路超時時間(單位:毫秒)。查看java.sql.Connection#setNetworkTimeout()
的 API 文檔以獲取更多資訊。
作為可選項,你也可以傳遞屬性給資料庫驅動。只需在屬性名加上「driver.」前綴即可,例如:
driver.encoding=UTF8
這將通過 DriverManager.getConnection(url, driverProperties) 方法傳遞值為 UTF8
的 encoding
屬性給資料庫驅動。
POOLED– 這種數據源的實現利用「池」的概念將 JDBC 連接對象組織起來,避免了創建新的連接實例時所必需的初始化和認證時間。 這種處理方式很流行,能使並發 Web 應用快速響應請求。
類型別名(typeAliases)
類型別名可為 Java 類型設置一個縮寫名字。 它僅用於 XML 配置,意在降低冗餘的全限定類名書寫。例如:
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>
當這樣配置時,Blog
可以用在任何使用 domain.blog.Blog
的地方。
也可以指定一個包名,MyBatis 會在包名下面搜索需要的 Java Bean,比如:
<typeAliases>
<package name="domain.blog"/>
</typeAliases>
每一個在包 domain.blog
中的 Java Bean,在沒有註解的情況下,會使用 Bean 的首字母小寫的非限定類名來作為它的別名。 比如 domain.blog.Author
的別名為 author**
;若有註解,則別名為其註解值**。見下面的例子:
@Alias("author")
public class Author {
...
}
注意: 第一種可以自己進行別名定義,但是第二種輕易不可以,如果強制修改則需要去實體類中去添加註解
下面是一些為常見的 Java 類型內建的類型別名。它們都是不區分大小寫的,注意,為了應對原始類型的命名重複,採取了特殊的命名風格。
別名 | 映射的類型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
設置(settings)
這是 MyBatis 中極為重要的調整設置,它們會改變 MyBatis 的運行時行為。 下表描述了設置中各項設置的含義、默認值等。
設置名 | 描述 | 有效值 | 默認值 |
---|---|---|---|
cacheEnabled | 全局性地開啟或關閉所有映射器配置文件中已配置的任何快取。 | true | false | true |
lazyLoadingEnabled | 延遲載入的全局開關。當開啟時,所有關聯對象都會延遲載入。 特定關聯關係中可通過設置 fetchType 屬性來覆蓋該項的開關狀態。 |
true | false | false |
useGeneratedKeys | 允許 JDBC 支援自動生成主鍵,需要資料庫驅動支援。如果設置為 true,將強制使用自動生成主鍵。儘管一些資料庫驅動不支援此特性,但仍可正常工作(如 Derby)。 | true | false | False |
---|---|---|---|
mapUnderscoreToCamelCase | 是否開啟駝峰命名自動映射,即從經典資料庫列名 A_COLUMN 映射到經典 Java 屬性名 aColumn。 | true | false | False |
logImpl | 指定 MyBatis 所用日誌的具體實現,未指定時將自動查找。 | SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING | 未設置 |
---|---|---|---|
映射器(mappers)
我們需要告訴 MyBatis 到哪裡去找到這些語句。
在自動查找資源方面,Java 並沒有提供一個很好的解決方案
所以最好的辦法是直接告訴 MyBatis 到哪裡去找映射文件。
你可以使用相對於類路徑的資源引用,或完全限定資源定位符(包括 file:///
形式的 URL),或類名和包名等。
例如:
<!-- 使用相對於類路徑的資源引用 -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
***第一個這是最常用的***
<!-- 使用映射器介面實現類的完全限定類名 -->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
注意:使用class文件綁定註冊的時候
1.介面要和它的mapper配置文件必須同名
2.介面和它的mapper配置文件必須在同一包下
************************************************************************
以下兩個不常用
<!-- 將包內的映射器介面實現全部註冊為映射器 -->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
<!-- 使用完全限定資源定位符(URL) -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>