Mybatis 相關(guān)執(zhí)行配置
設(shè)置相關(guān)的Configuration配置信息
Configuration configuration = new Configuration();
//設(shè)置環(huán)境配置
//通過(guò)JdbcTransactionFactory創(chuàng)建jdbc Transaction事務(wù)管理器
//創(chuàng)建DataSource
Environment environment = new Environment("development", new JdbcTransactionFactory(),
new UnpooledDataSource("org.***.jdbcDriver", "jdbc:***", "user", "123456"));
//2. 設(shè)置環(huán)境信息
configuration.setEnvironment(environment);
// 3. 設(shè)置是否自增
configuration.setUseGeneratedKeys(true);
configuration.addMapper(Mapper.class);
-
設(shè)置環(huán)境變量Environment,也可以通過(guò)XML方法配置
<environments default="development"> <environment id="development"> </environment> </environments>- 默認(rèn)使用的環(huán)境 ID(比如:default="development")。
- 每個(gè) environment 元素定義的環(huán)境 ID(比如:id="development")。
MyBatis可以配置多種環(huán)境,簡(jiǎn)單來(lái)說(shuō)就是可以將 SQL 映射應(yīng)用于多種數(shù)據(jù)庫(kù)。例如,開(kāi)發(fā)、測(cè)試和生產(chǎn)環(huán)境需要有不同的配置;或者想在具有相同 Schema 的多個(gè)生產(chǎn)數(shù)據(jù)庫(kù)中使用相同的 SQL 映射。
通過(guò)TransactionFactory設(shè)置事務(wù)管理器,也可以XML方法,如下
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="..." value="..."/>
</transactionManager>
</environment>
</environments>
在 MyBatis 中有兩種事務(wù)管理器JDBC和MANAGED( type="JDBC/MANAGED")
JDBC – 直接使用了 JDBC 提交和回滾功能,它依賴(lài)從數(shù)據(jù)源獲得的連接來(lái)管理事務(wù)作用域。 ****
-
MANAGED – 讓容器來(lái)管理事務(wù)的整個(gè)生命周期。從不提交或回滾一個(gè)連接, 默認(rèn)情況下它會(huì)關(guān)閉連接。如果一些容器不希望連接被關(guān)閉,因此需要將closeConnection屬性設(shè)置為 false 來(lái)阻止默認(rèn)的關(guān)閉行為。例如:
<transactionManager type="MANAGED"> <property name="closeConnection" value="false"/> </transactionManager>
這兩種事務(wù)管理器類(lèi)型都不需要設(shè)置任何屬性。用 TransactionFactory 接口實(shí)現(xiàn)來(lái)代替如JdbcTransactionFactory和ManagedTransactionFactory。
public interface TransactionFactory {
default void setProperties(Properties props) { // 從 3.5.2 開(kāi)始,該方法為默認(rèn)方法
// 空實(shí)現(xiàn)
}
Transaction newTransaction(Connection conn);
Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);
}
在事務(wù)管理器實(shí)例化后, XML 中配置的屬性將會(huì)被傳遞給 setProperties() 方法??梢酝ㄟ^(guò) Transaction 接口的實(shí)現(xiàn)類(lèi)來(lái)實(shí)現(xiàn)相關(guān)功能,如JdbcTransaction,ManagedTransaction,下發(fā)表格展示了JdbcTransaction,ManagedTransaction的特性和區(qū)別:
public interface Transaction {
Connection getConnection() throws SQLException;
void commit() throws SQLException;
void rollback() throws SQLException;
void close() throws SQLException;
Integer getTimeout() throws SQLException;
}
| JdbcTransaction | ManagedTransaction |
|---|---|
| 屬性訪問(wèn)權(quán)限:protected | 屬性訪問(wèn)權(quán)限:private |
| public void commit() throws SQLException { if (connection != null && !connection.getAutoCommit()) { if (log.isDebugEnabled()) { log.debug("Committing JDBC Connection [" + connection + "]"); } connection.commit(); } } |
public void commit() throws SQLException { // Does nothing } |
| public void rollback() throws SQLException { if (connection != null && !connection.getAutoCommit()) { if (log.isDebugEnabled()) { log.debug("Rolling back JDBC Connection [" + connection + "]"); } connection.rollback(); } } |
public void rollback() throws SQLException { // Does nothing } |
| protected void openConnection() throws SQLException { if (log.isDebugEnabled()) { log.debug("Opening JDBC Connection"); } connection = dataSource.getConnection(); if (level != null) { connection.setTransactionIsolation(level.getLevel()); } **setDesiredAutoCommit(autoCommit); **//設(shè)置自動(dòng)提交 } |
protected void openConnection() throws SQLException { if (log.isDebugEnabled()) { log.debug("Opening JDBC Connection"); } this.connection = this.dataSource.getConnection(); if (this.level != null) { this.connection.setTransactionIsolation(this.level.getLevel()); } } |
| public void close() throws SQLException { if (connection != null) { resetAutoCommit(); if (log.isDebugEnabled()) { log.debug("Closing JDBC Connection [" + connection + "]"); } connection.close(); } } |
public void close() throws SQLException { if (this.closeConnection && this.connection != null) { if (log.isDebugEnabled()) { log.debug("Closing JDBC Connection [" + this.connection + "]"); } this.connection.close(); } } |
-
數(shù)據(jù)源(dataSource),Mybatis3一般有三種數(shù)據(jù)源類(lèi)型(UNPOOLED/POOLED/JNDI):
UNPOOLED– 每次請(qǐng)求都會(huì)打開(kāi)和關(guān)閉連接。面向?qū)?shù)據(jù)庫(kù)連接可用性要求不高的程序。 UNPOOLED 類(lèi)型的數(shù)據(jù)源需要配置如下:
-
driver– 這是 JDBC 驅(qū)動(dòng)的 Java 類(lèi)全限定名(并不是 JDBC 驅(qū)動(dòng)中可能包含的數(shù)據(jù)源類(lèi))。
-
url– 這是數(shù)據(jù)庫(kù)的 JDBC URL 地址。 -
username– 登錄數(shù)據(jù)庫(kù)的用戶名。 -
password– 登錄數(shù)據(jù)庫(kù)的密碼。 -
defaultTransactionIsolationLevel– 默認(rèn)的連接事務(wù)隔離級(jí)別。 -
defaultNetworkTimeout– 等待數(shù)據(jù)庫(kù)操作完成的默認(rèn)網(wǎng)絡(luò)超時(shí)時(shí)間(單位:毫秒)。
POOLED– 支持?jǐn)?shù)據(jù)庫(kù)連接池,避免創(chuàng)建新的連接實(shí)例時(shí)所必需的初始化和認(rèn)證時(shí)間。 配置 POOLED 數(shù)據(jù)源的屬性:
-
poolMaximumActiveConnections– 最大連接數(shù)量,默認(rèn)值:10 -
poolMaximumIdleConnections– 任意時(shí)間可能存在的空閑連接數(shù)。(注意:任意時(shí)間,默認(rèn)值5) -
poolMaximumCheckoutTime– 在被強(qiáng)制返回之前,池中連接被檢出(checked out)時(shí)間,默認(rèn)值:20000 毫秒( 20 秒) -
poolTimeToWait– 線程等待時(shí)間,獲取連接超時(shí),連接池會(huì)打印狀態(tài)日志,并重新嘗試獲取一個(gè)連接(避免在誤配置的情況下一直失敗且不打印日志),默認(rèn)值:20000 毫秒(即 20 秒)。 -
poolMaximumLocalBadConnectionTolerance– 這是一個(gè)關(guān)于壞連接容忍度的底層設(shè)置, 作用于每一個(gè)嘗試從緩存池獲取連接的線程。 如果這個(gè)線程獲取到的是一個(gè)壞的連接,那么這個(gè)數(shù)據(jù)源允許這個(gè)線程嘗試重新獲取一個(gè)新的連接,但是這個(gè)重新嘗試的次數(shù)不應(yīng)該超過(guò)poolMaximumIdleConnections與poolMaximumLocalBadConnectionTolerance之和。 默認(rèn)值:3 -
poolPingQuery– 發(fā)送到數(shù)據(jù)庫(kù)的偵測(cè)查詢(xún),用來(lái)檢驗(yàn)連接是否正常工作并準(zhǔn)備接受請(qǐng)求。默認(rèn)是“NO PING QUERY SET”,保證了多數(shù)數(shù)據(jù)庫(kù)驅(qū)動(dòng)出錯(cuò)時(shí)返回適當(dāng)?shù)腻e(cuò)誤消息。 -
poolPingEnabled– 是否啟用偵測(cè)查詢(xún)。若開(kāi)啟,需要設(shè)置poolPingQuery屬性為一個(gè)可執(zhí)行的 SQL 語(yǔ)句(最好是一個(gè)速度非??斓?SQL 語(yǔ)句),默認(rèn)值:false。 -
poolPingConnectionsNotUsedFor– poolPingQuery 的頻率??梢栽O(shè)置為和數(shù)據(jù)庫(kù)連接超時(shí)時(shí)間一樣,避免不必要的偵測(cè),默認(rèn)值:0(即所有連接每一時(shí)刻都被偵測(cè) — 僅當(dāng) poolPingEnabled 為 true 時(shí)適用)。
JNDI – 在 EJB 或應(yīng)用服務(wù)器等容器中使用,容器可以集中或在外部配置數(shù)據(jù)源,然后放在 JNDI 上下文引用。配置只需要兩個(gè)屬性:
-
initial_context– 用來(lái)在 InitialContext 中尋找上下文(即,initialContext.lookup(initial_context))。是個(gè)可選屬性,如果忽略,那么將會(huì)直接從 InitialContext 中尋找 data_source 屬性。 -
data_source– 引用數(shù)據(jù)源實(shí)例位置的上下文路徑。提供了 initial_context 配置時(shí),會(huì)在其返回的上下文中進(jìn)行查找,沒(méi)有提供時(shí)則直接在 InitialContext 中查找。
可以通過(guò)添加前綴“env.”直接把屬性傳遞給 InitialContext。比如:
-
env.encoding=UTF8// InitialContext 實(shí)例化時(shí)往它的構(gòu)造方法傳遞值為UTF8的encoding屬性
一般通過(guò)DataSourceFactory` 來(lái)使用第三方數(shù)據(jù)源實(shí)現(xiàn):
public interface DataSourceFactory { void setProperties(Properties props); DataSource getDataSource(); }org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory可被用作父類(lèi)來(lái)構(gòu)建新的數(shù)據(jù)源適配器,比如下面這段插入 C3P0 數(shù)據(jù)源所必需的代碼:import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory; import com.mchange.v2.c3p0.ComboPooledDataSource; public class C3P0DataSourceFactory extends UnpooledDataSourceFactory { public C3P0DataSourceFactory() { this.dataSource = new ComboPooledDataSource(); } }為了令其工作,記得在配置文件中為每個(gè)希望 MyBatis 調(diào)用的 setter 方法增加對(duì)應(yīng)的屬性。 下面是一個(gè)可以連接至 PostgreSQL 數(shù)據(jù)庫(kù)的例子:
<dataSource type="org.myproject.C3P0DataSourceFactory"> <property name="driver" value="org.postgresql.Driver"/> <property name="url" value="jdbc:postgresql:mydb"/> <property name="username" value="postgres"/> <property name="password" value="root"/> </dataSource> -
參考資料
mybatis中文api:https://mybatis.org/mybatis-3/zh/configuration.html。