MyBatis配置文件(七)--environments運行環境


一、environments配置信息:

environments的作用是用來配置數據庫信息,可以配置多個,其有兩個可配的子元素,分別是:事務管理器transactionManager和數據源dataSource,先看一下我配置的例子:

 1 <!-- 環境模式:development開發模式 work工作模式 -->
 2     <environments default="development">
 3         <!--環境變量 -->
 4         <environment id="development">
 5             <!--事務管理器 -->
 6             <transactionManager type="JDBC" />
 7             <!--數據源 -->
 8             <dataSource type="POOLED">
 9                 <property name="driver" value="${db.driver}" />
10                 <property name="url" value="${db.url}" />
11                 <property name="username" value="${db.username}" />
12                 <property name="password" value="${db.pwd}" />
13             </dataSource>
14         </environment>
15     </environments>

配置項說明:

1⃣️environments-default:該屬性指定當前的環境,有development和work兩種選擇,默認是development開發模式;

2⃣️environment-id:該屬性是每個environment定義的環境,也有development和work兩種選擇,默認是development開發模式;

3⃣️transactionManager-type:該屬性是配置事務管理器的類型,mybatis中有JDBC和MANAGED兩種,一次只能配置一個,后面會介紹;

4⃣️dataSource-type:該屬性用來配置數據源類型,有UNPOOLED、POOLED和JNDI三種選擇,后面會介紹;

5⃣️dataSource中的property元素就是數據庫相關的信息

注意:environment可以配置多個,但是如果同一種模式,如development模式,配置了兩個環境environment,mybatis會用后面的覆蓋前面的,如下配置:

 1 <environments default="development">
 2         <!--環境變量 -->
 3         <environment id="development">
 4             <!--事務管理器 -->
 5             <transactionManager type="MANAGED" />
 6             <!--數據源 -->
 7             <dataSource type="POOLED">
 8                 <property name="driver" value="${db.driver}" />
 9                 <property name="url" value="${db.url}" />
10                 <property name="username" value="${db.username}" />
11                 <property name="password" value="${db.pwd}" />
12             </dataSource>
13         </environment>
14         <!--環境變量 -->
15         <environment id="development">
16             <!--事務管理器 -->
17             <transactionManager type="JDBC" />
18             <!--數據源 -->
19             <dataSource type="POOLED">
20                 <property name="driver" value="${db.driver}" />
21                 <property name="url" value="${db.url}" />
22                 <property name="username" value="${db.username}" />
23                 <property name="password" value="${db.pwd}" />
24             </dataSource>
25         </environment>
26     </environments>

上面的例子中我配了兩個environment,但是它們的環境模式都是開發模式,此時在開發環境中生效的是后面的,即事務管理器為JDBC的配置,所以一般多個最多配置兩個環境,且開發模式不同,一個是開發環境,一個是工作環境。下面通過代碼獲取環境配置信息:

1    /**
2      * 獲取環境信息
3      */
4     public static void getEnvironment() {
5         SqlSession sqlSession = getSqlSession();
6         Environment env = sqlSession.getConfiguration().getEnvironment();
7         TransactionFactory tf = env.getTransactionFactory();
8         System.out.println(tf.getClass().getSimpleName());
9     }

 輸出結果:

1 JdbcTransactionFactory

可以看到返回的事務管理器類型為JdbcTransactionFactory,而當我在配置中把事務管理器改成MANAGED時,會獲取到ManagedTransactionFactory類型。下面分開介紹事務管理器和數據源的配置內容。

二、transactionManager事務管理器配置

在MyBatis中,transactionManager提供了兩個實現類,都需要實現接口Transaction,我們可以查看以下它的源代碼:

 1 public interface Transaction {
 2 
 3 
 4   Connection getConnection() throws SQLException;
 5 
 6   void commit() throws SQLException;
 7  
 8   void rollback() throws SQLException;
 9  
10   void close() throws SQLException;
11  
12   Integer getTimeout() throws SQLException;
13   
14 }

從提供的方法中可以知道,它主要完成提交、回滾、關閉數據庫的事務。MyBatis中為Transaction接口提供了兩個實現類,分別是JdbcTransaction和ManagedTransaction,並且分別對應着JdbcTransactionFactory和ManagedTransactionFactory兩個工廠,這兩個工廠實現了TransactionFactory這個接口,當我們在配置文件中通過transactionManager的type屬性配置事務管理器類型的時候,mybatis就會自動從對應的工廠獲取實例。下面說一下這兩者的區別:

1⃣️JDBC使用JdbcTransactionFactory工廠生成的JdbcTransaction對象實現,以JDBC的方式進行數據庫的提交、回滾等操作;

2⃣️MANAGED使用ManagedTransactionFactory工廠生成的ManagedTransaction對象實現,它的提交和回滾不需要任何操作,而是把事務交給容器進行處理,默認情況下會關閉連接,如果不希望默認關閉,只要將其中的closeConnection屬性設置為false即可。

我在測試的過程中發現的最明顯的區別就是,如果我使用JDBC的事務處理方式,當我向數據庫中插入一條數據時,在調用完插入接口執行SQL之后,必須 執行sqlSession.commit();進行提交,否則雖然插入成功但是數據庫中還是看不到剛才插入的數據;而使用MANAGED方式就不一樣了,只需調用接口即可,無需手動提交。

當然,除了使用默認的,我們還可以根據需要自定義一個事務管理器,需要以下三步:

第一步:創建一個事務管理類,繼承ManagedTransaction或JdbcTransaction類或實現Transaction接口;

 1 /**
 2  * 定義自己的事務管理器
 3  */
 4 public class MyTransaction extends JdbcTransaction implements Transaction {
 5 
 6     // 重寫父類方法
 7     public MyTransaction(Connection connection) {
 8         super(connection);
 9     }
10 
11     public MyTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {
12         super(ds, desiredLevel, desiredAutoCommit);
13     }
14 }

第二步:創建一個事務管理工廠類,實現TransactionFactory接口,提供生產事務處理相關接口;

 1 /**
 2  * 定義自己的事務管理器,實現獲取連接、提交、回滾、關閉數據庫連接等操作
 3  */
 4 public class MyTransaction extends JdbcTransaction implements Transaction {
 5 
 6     public MyTransaction(Connection connection) {
 7         super(connection);
 8     }
 9 
10     public MyTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {
11         super(ds, desiredLevel, desiredAutoCommit);
12     }
13 
14     @Override
15     public Connection getConnection() throws SQLException {
16         return super.getConnection();
17     }
18 
19     @Override
20     public void commit() throws SQLException {
21         super.commit();
22     }
23 
24     @Override
25     public void rollback() throws SQLException {
26         super.rollback();
27     }
28 
29     @Override
30     public void close() throws SQLException {
31         super.close();
32     }
33 
34     @Override
35     public Integer getTimeout() throws SQLException {
36         return super.getTimeout();
37     }
38 }

第三步:配置自定義事務管理器

1 <transactionManager type="com.daily.objectfactory.MyTransactionFactory" />

注意⚠️:這個地方配置的是自定義的工廠類,而不是事務管理類,因為mybatis是根據配置的工廠獲取具體實例對象的。

要不是親手實踐,差點就忽略了這點呢!!!

通過以上三步就完成了自定義事務管理器的配置,其實我們還可以在別名設置這個工廠的別名,然后在此處引用,如下:

先在別名中配置工廠所在的包

1 <typeAliases>
2         <!-- 對包進行掃描,可以批量進行別名設置,設置規則是:獲取類名稱,將其第一個字母變為小寫 -->
3         <package name="com.daily.objectfactory" />
4 </typeAliases>

然后按照規則,該包下所有類的別名是將類的第一個字母變成小寫,所以我自定義的這個事務管理器工廠MyTransactionFactory的別名就是myTransactionFactory,這樣我就可以在事務管理配置中使用該別名了,如下:

1 <!--事務管理器 -->
2 <transactionManager type="myTransactionFactory" />

三、dataSource數據源配置

在mybatis中,數據庫是通過PooledDataSourceFactory、UnpooledDataSourceFactory和JndiDataSourceFactory三個工廠類來提供,前兩者分別產生PooledDataSource和UnpooledDataSource類對象,第三個則會根據JNDI的信息拿到外部容器實現的數據庫連接對象,但是不管怎樣,它們最后都會生成一個實現了DataSource接口的數據庫連接對象。

它們的配置信息如下:

1 <dataSource type="POOLED">
2 <dataSource type="UNPOOLED">
3 <dataSource type="JNDI">

這三種數據源的意義如下:

1⃣️UNPOOLED

采用非數據庫池的管理方式,每次請求都會新建一個連接,所以性能不是很高,使用這種數據源的時候,我們可以配置以下屬性:

driver數據庫驅動名

url數據庫連接URL

username用戶名

password密碼

defaultTransactionIsolationLevel默認的事務隔離級別,如果要傳遞屬性給驅動,則屬性的前綴為driver

2⃣️POOLED

采用連接池的概念將數據庫鏈接對象Connection組織起來,可以在初始化時創建多個連接,使用時直接從連接池獲取,避免了重復創建連接所需的初始化和認證時間,從而提升了效率,所以這種方式比較適合對性能要求高的應用中。除了UNPOOLED中的配置屬性之外,還有下面幾個針對池子的配置:

poolMaximumActiveConnections:任意時間都會存在的連接數,默認值為10

poolMaxmumIdleConnections:可以空閑存在的連接數

poolMaxmumCheckoutTime:在被強制返回之前,檢查出存在空閑連接的等待時間。即如果有20個連接,只有一個空閑,在這個空閑連接被找到之前的等待時間就用這個屬性配置。

poolTimeToWait:等待一個數據庫連接成功所需的時間,如果超出這個時間則嘗試重新連接。

還有其他的一些配置,不詳述了。

3⃣️JNDI

數據源JNDI的實現是為了能在如EJB或應用服務器這類容器中使用,容器可以集中或在外部配置數據源,然后放置一個JNDI上下文的引用。這種數據源只需配置兩個屬性:

initial_context:用來在InitialContext中尋找上下文。可選,如果忽略,data_source屬性將會直接從InitialContext中尋找;

data_source:引用數據源實例位置上下文的路徑。當提供initial_context配置時,data_source會在其返回的上下文進行查找,否則直接從InitialContext中查找。

除了上述三種數據源之外,mybatis還提供第三方數據源,如DBCP,但是需要我們自定義數據源工廠並進行配置,這一點暫時不做研究。

以上就是environments運行環境的配置。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM