建站知識互聯網整合營銷推廣
MyBatis支持配置多個環(huán)境,這有助于將您的SQL映射應用于多個數據庫,無論出于何種原因。例如,您可能希望為開發(fā)、測試和生產環(huán)境使用不同的配置?;蛘?#xff0c;您可能有多個共享相同模式的生產數據庫,并且想要在兩者上使用相同的SQL映射。有許多使用情況可以考慮。
有一件重要的事需要記住:雖然您可以配置多個環(huán)境,但在每個SqlSessionFactory實例中只能選擇一個環(huán)境。
因此,如果您想要連接到兩個數據庫,您需要創(chuàng)建兩個SqlSessionFactory實例,每個實例連接一個數據庫。對于三個數據庫,您需要三個實例,依此類推。這是非常容易記住的。
- 每個數據庫使用一個SqlSessionFactory實例。
要指定要構建的環(huán)境,只需將其作為可選參數傳遞給SqlSessionFactoryBuilder。接受環(huán)境參數的兩種簽名是:
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties);
?如果省略了環(huán)境參數,則會加載默認環(huán)境,如下所示:
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, properties);
environments元素定義了環(huán)境的配置。
<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>
請注意以下關鍵部分:
- 默認環(huán)境ID(例如 default="development")。
- 每個定義環(huán)境的環(huán)境ID(例如 id="development")。
- 事務管理器的配置(例如 type="JDBC")。
- 數據源的配置(例如 type="POOLED")。
默認環(huán)境和環(huán)境ID可以根據您的喜好進行命名,只要確保默認環(huán)境與其中一個環(huán)境ID匹配即可。
transactionManager
MyBatis包含兩種事務管理器類型(即type="[JDBC|MANAGED]"),它們分別是:
- JDBC – 這個配置直接使用JDBC的提交和回滾功能。它依賴于從數據源(dataSource)獲取的連接來管理事務的范圍。默認情況下,它在關閉連接時啟用自動提交,以保證與一些驅動程序的兼容性。然而,對于某些驅動程序來說,啟用自動提交不僅是不必要的,而且還是一個昂貴的操作。因此,從版本3.5.10開始,您可以通過將“skipSetAutoCommitOnClose”屬性設置為true來跳過這一步驟。例如:?
<transactionManager type="JDBC"><property name="skipSetAutoCommitOnClose" value="true"/>
</transactionManager>
- ?MANAGED – 這個配置實際上幾乎不做任何操作。它不會提交或回滾連接。相反,它讓容器來管理事務的整個生命周期(例如JEE應用服務器的上下文)。默認情況下,它會關閉連接。然而,某些容器不希望出現這種情況,因此如果您需要阻止它關閉連接,請將“closeConnection”屬性設置為false。例如:
<transactionManager type="MANAGED"><property name="closeConnection" value="false"/>
</transactionManager>
?注意:如果您計劃將MyBatis與Spring一起使用,就不需要配置任何事務管理器,因為Spring模塊會設置自己的事務管理器,覆蓋任何先前設置的配置。
這兩種事務管理器類型都不需要任何屬性。然而,它們都是類型別名,換句話說,您可以使用自己的完全限定類名或類型別名來引用您自己實現的TransactionFactory接口。
public interface TransactionFactory {default void setProperties(Properties props) { // Since 3.5.2, change to default method// NOP}Transaction newTransaction(Connection conn);Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit);
}
?在XML中配置的任何屬性都將在實例化后傳遞給setProperties()方法。您的實現還需要創(chuàng)建一個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 DataSource接口配置JDBC連接對象的來源。
大多數MyBatis應用程序將按示例配置一個dataSource。但是,這并不是必需的。需要注意的是,為了方便延遲加載(Lazy Loading),這個dataSource是必需的。
有三種內置的數據源類型(type="[UNPOOLED|POOLED|JNDI]"):
UNPOOLED - 這個數據源的實現在每次請求時都會打開和關閉一個連接。雖然速度稍慢,但對于不需要立即可用連接性能的簡單應用程序來說,這是一個不錯的選擇。不同的數據庫在這個性能方面也有所不同,所以對于某些數據庫來說,池化連接可能不太重要,這種配置會更理想。UNPOOLED數據源有以下屬性可以配置:
- driver - 這是JDBC驅動程序的完全限定Java類名(如果您的驅動程序包含一個DataSource類,則不是它)。
- url - 這是您數據庫實例的JDBC URL。
- username - 用于登錄的數據庫用戶名。
- password - 用于登錄的數據庫密碼。
- defaultTransactionIsolationLevel - 連接的默認事務隔離級別??梢允褂靡韵骂A定義常量來設置:NONE, READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE。
- defaultNetworkTimeout - 默認的網絡超時值,以毫秒為單位,用于等待數據庫操作完成。有關詳細信息,請參閱java.sql.Connection#setNetworkTimeout()的API文檔。
可選地,您還可以向數據庫驅動程序傳遞屬性。要做到這一點,將屬性前綴為 ?driver.
?,例如:
driver.encoding=UTF8
這將通過DriverManager.getConnection(url, driverProperties)方法向您的數據庫驅動程序傳遞屬性編碼,屬性名稱為encoding,值為UTF8。
POOLED - 這是一種DataSource的實現,它可以池化JDBC連接對象,以避免創(chuàng)建新的連接實例所需的初始連接和身份驗證時間。這是并發(fā)Web應用程序實現最快響應的常用方法。
除了上述的(UNPOOLED)屬性之外,還有許多其他屬性可用于配置POOLED數據源。以下是一些常用的屬性:
- 屬性
?poolMaximumActiveConnections
?表示同時存在的活動(即正在使用)連接的數量。默認值為10。 - 屬性
?poolMaximumIdleConnections
?表示同時存在的空閑連接的數量。 - 屬性
?poolMaximumCheckoutTime
?表示一個連接在被"check out"(即被獲取)之后可以持續(xù)存在的最長時間,超過此時間將被強制返回到連接池。默認值為20000毫秒(即20秒)。 - 屬性
?poolTimeToWait
?是一個低級設置,用于在獲取連接花費異常長的時間時,給連接池一個機會打印日志狀態(tài)并重新嘗試獲取連接(以避免在連接池配置錯誤的情況下永遠靜默失敗)。默認值為20000毫秒(即20秒)。 - 屬性
?poolMaximumLocalBadConnectionTolerance
?是關于線程容忍的壞連接數量的低級設置。如果一個線程獲取到一個壞連接,它可能還有另外一次機會重新嘗試獲取到另一個有效的連接。但重試次數不應超過poolMaximumIdleConnections和poolMaximumLocalBadConnectionTolerance之和。默認值為3(自3.4.5起)。 - 屬性
?poolPingQuery
?是發(fā)送給數據庫的Ping查詢,用于驗證連接是否工作正常,并準備接受請求。默認值為"NO PING QUERY SET",這會導致大多數數據庫驅動程序以良好的錯誤消息失敗。 - 屬性
?poolPingEnabled
?用于啟用或禁用ping查詢。如果啟用,還必須設置具有有效SQL語句的poolPingQuery屬性(最好是一個非??斓牟樵?#xff09;。默認值為false。 - 屬性
?poolPingConnectionsNotUsedFor
?配置poolPingQuery的使用頻率??梢詫⑵湓O置為與數據庫連接的典型超時時間相匹配,以避免不必要的ping查詢。默認值為0(即每次都對所有連接進行ping查詢,但前提是poolPingEnabled為true)。?
JNDI(Java命名和目錄接口)的這種DataSource實現是為與EJB或應用服務器等容器一起使用而設計的。這些容器可以集中或外部地配置DataSource,并將對它的引用放置在JNDI上下文中。這種DataSource配置只需要兩個屬性:
- initial_context – 這個屬性用于從InitialContext中查找上下文(即initialContext.lookup(initial_context))。這個屬性是可選的,如果省略,則會直接在InitialContext中查找data_source屬性。
- data_source – 這是一個上下文路徑,用于找到對DataSource實例的引用。它會根據initial_context查找返回的上下文進行查找,或者如果沒有提供initial_context,則會在InitialContext中直接進行查找。?
與其他DataSource配置類似,可以通過在屬性前加上"env."的方式將屬性直接發(fā)送給InitialContext。例如:
env.encoding=UTF8
這將會在實例化InitialContext的構造函數中將屬性"encoding"和值"UTF8"發(fā)送給InitialContext。
通過實現接口org.apache.ibatis.datasource.DataSourceFactory,您可以插入任何第三方的DataSource:
public interface DataSourceFactory {void setProperties(Properties props);DataSource getDataSource();
}
?org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory可以作為構建新的數據源適配器的超類使用。例如,下面是將C3P0插入的代碼示例:
import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory;
import com.mchange.v2.c3p0.ComboPooledDataSource;public class C3P0DataSourceFactory extends UnpooledDataSourceFactory {public C3P0DataSourceFactory() {this.dataSource = new ComboPooledDataSource();}
}
?要設置它,為您希望MyBatis調用的每個setter方法添加一個屬性。下面是一個連接到PostgreSQL數據庫的示例配置:
<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>
?