一、什么是配置之屬性優化
在解答這個問題之前我們應該先明白MyBatis的配置有哪些?
官方檔案中文網:配置_MyBatis中文網,
我們還是直接看官方檔案中給出的內容:
MyBatis 的組態檔包含了會深深影響 MyBatis 行為的設定和屬性資訊, 配置檔案的頂層結構如下:
configuration(配置)
properties(屬性)
settings(設定)
typeAliases(型別別名)
typeHandlers(型別處理器)
objectFactory(物件工廠)
plugins(插件)
environments(環境配置)
environment(環境變數)
transactionManager(事務管理器)
dataSource(資料源)
databaseIdProvider(資料庫廠商標識)
mappers(映射器)
ok,看到上面的配置結構,我們會發現有一些是我們接觸過的,沒錯,就是environments(環境配置)和mappers(映射器),我們在建立第一個MyBatis程式的時候,就在mybatis-config.xml組態檔中對它們進行了配置,當時他們是這樣的:
<?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> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/MyBaties?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/jms/dao/UserMapper.xml"/> </mappers> </configuration>
既然如此,我們在對屬性進行優化之前,先了解environments(環境配置)的一些內容,
環境配置(environments)
MyBatis 可以配置成適應多種環境,這種機制有助于將 SQL 映射應用于多種資料庫之中, 現實情況下有多種理由需要這么做,例如,開發、測驗和生產環境需要有不同的配置;或者想在具有相同 Schema 的多個生產資料庫中使用相同的 SQL 映射,還有許多類似的使用場景,
不過要記住:盡管可以配置多個環境,但每個 SqlSessionFactory 實體只能選擇一種環境,
這是官方檔案的內容,其中說可以配置多種環境,也就是說<environment id="development">...</environment>可以有多個,我們通過default="..."選擇其中一個,就像下面的例子:
<?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> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/MyBaties?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> <environment id="test"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/MyBaties?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/jms/dao/UserMapper.xml"/> </mappers> </configuration>
這里我配置了兩個環境,一個id為development,還有一個id為test,但是由于default="development",所以我選擇的是id為development的環境,
OK,明白了default和id所代表的含義,我們接下來看<transactionManager type="JDBC"/>事務管理器,還是先看官方給出的檔案:
事務管理器(transactionManager)
在 MyBatis 中有兩種型別的事務管理器(也就是 type="[JDBC|MANAGED]"):
JDBC – 這個配置直接使用了 JDBC 的提交和回滾設施,它依賴從資料源獲得的連接來管理事務作用域,
MANAGED – 這個配置幾乎沒做什么,它從不提交或回滾一個連接,而是讓容器來管理事務的整個生命周期(比如 JEE 應用服務器的背景關系), 默認情況下它會關閉連接,然而一些容器并不希望連接被關閉,因此需要將 closeConnection 屬性設定為 false 來阻止默認的關閉行為,
提示:如果你正在使用 Spring + MyBatis,則沒有必要配置事務管理器,因為 Spring 模塊會使用自帶的管理器來覆寫前面的配置,
所以說,事務管理器其實有JDBC和MANAGED兩種,但是我們一般都會選擇JDBC,
<dataSource type="POOLED">資料源:
資料源(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 應用快速回應請求,
除了上述提到 UNPOOLED 下的屬性外,還有更多屬性用來配置 POOLED 的資料源:
poolMaximumActiveConnections – 在任意時間可存在的活動(正在使用)連接數量,默認值:10
poolMaximumIdleConnections – 任意時間可能存在的空閑連接數,
poolMaximumCheckoutTime – 在被強制回傳之前,池中連接被檢出(checked out)時間,默認值:20000 毫秒(即 20 秒)
poolTimeToWait – 這是一個底層設定,如果獲取連接花費了相當長的時間,連接池會列印狀態日志并重新嘗試獲取一個連接(避免在誤配置的情況下一直失敗且不列印日志),默認值:20000 毫秒(即 20 秒),
poolMaximumLocalBadConnectionTolerance – 這是一個關于壞連接容忍度的底層設定, 作用于每一個嘗試從快取池獲取連接的執行緒, 如果這個執行緒獲取到的是一個壞的連接,那么這個資料源允許這個執行緒嘗試重新獲取一個新的連接,但是這個重新嘗試的次數不應該超過 poolMaximumIdleConnections 與 poolMaximumLocalBadConnectionTolerance 之和, 默認值:3(新增于 3.4.5)
poolPingQuery – 發送到資料庫的偵測查詢,用來檢驗連接是否正常作業并準備接受請求,默認是“NO PING QUERY SET”,這會導致多數資料庫驅動出錯時回傳恰當的錯誤訊息,
poolPingEnabled – 是否啟用偵測查詢,若開啟,需要設定 poolPingQuery 屬性為一個可執行的 SQL 陳述句(最好是一個速度非常快的 SQL 陳述句),默認值:false,
poolPingConnectionsNotUsedFor – 配置 poolPingQuery 的頻率,可以被設定為和資料庫連接超時時間一樣,來避免不必要的偵測,默認值:0(即所有連接每一時刻都被偵測 — 當然僅當 poolPingEnabled 為 true 時適用),
JNDI – 這個資料源實作是為了能在如 EJB 或應用服務器這類容器中使用,容器可以集中或在外部配置資料源,然后放置一個 JNDI 背景關系的資料源參考,這種資料源配置只需要兩個屬性:
initial_context – 這個屬性用來在 InitialContext 中尋找背景關系(即,initialContext.lookup(initial_context)),這是個可選屬性,如果忽略,那么將會直接從 InitialContext 中尋找 data_source 屬性,
data_source – 這是參考資料源實體位置的背景關系路徑,提供了 initial_context 配置時會在其回傳的背景關系中進行查找,沒有提供時則直接在 InitialContext 中查找,
和其他資料源配置類似,可以通過添加前綴“env.”直接把屬性傳遞給 InitialContext,比如:
env.encoding=UTF8
這就會在 InitialContext 實體化時往它的構造方法傳遞值為 UTF8 的 encoding 屬性,
看了以上檔案,我們主要要了解事務管理器的默認是JDBC,資料源默認的是POOLED,
接下來就只剩下環境配置中<property />標簽的內容了,很明顯,這就是屬性標簽,對于組態檔,官方給出的默認的格式是這樣的:
<property name="driver" value="https://www.cnblogs.com/jmsstudy/p/${driver}"/>
<property name="url" value="https://www.cnblogs.com/jmsstudy/p/${url}"/>
<property name="username" value="https://www.cnblogs.com/jmsstudy/p/${username}"/>
<property name="password" value="https://www.cnblogs.com/jmsstudy/p/${password}"/>
那么我們怎么樣才能和官方這種默認的格式匹配起來呢,現在我們就需要對屬性進行優化了,
屬性(properties)
這些屬性可以在外部進行配置,并可以進行動態替換,你既可以在典型的 Java 屬性檔案中配置這些屬性,也可以在 properties 元素的子元素中設定,
例如:
<properties resource="org/mybatis/example/config.properties"> <property name="username" value="https://www.cnblogs.com/jmsstudy/p/dev_user"/> <property name="password" value="https://www.cnblogs.com/jmsstudy/p/F2Fa3!33TYyg"/> </properties>
官方檔案中是這樣說明的,我們將屬性在外部配置或在properties的子元素中設定就是對屬性的優化,
二、怎么進行屬性的優化
1.在java屬性檔案中配置
(1)首先建立一個屬性檔案db.properties,其中的內容如下:
diver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/MyBaties?useSSL=true&useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
(2)修改mybatis-config.xml組態檔
<?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 resource="db.properties"> </properties> <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> <mappers> <mapper resource="com/jms/dao/UserMapper.xml"/> </mappers> </configuration>
我們通過<properties resource="db.properties"> </properties>對db.properties檔案進行了參考,在這種配置下我們去測驗是完全可以的,
(2)直接在<properties>元素的子元素中進行設定
我現在先把db.properties檔案中的username和password兩項刪掉,再去將<properties>元素內容修改為以下樣式:
<properties resource="db.properties"> <property name="username" value="root"/> <property name="password" value="123456"/> </properties>
此時我們去測驗依舊沒有問題,
以上就是對屬性的優化,那么問題來了,既可以直接在環境配置中賦值,又可以通過properties檔案和<properties>元素的子元素堆屬性進行配置,當其中有重復的屬性配置時,該使用哪一個配置呢?
官方在檔案中作出了以下規定:
如果一個屬性在不只一個地方進行了配置,那么,MyBatis 將按照下面的順序來加載:
首先讀取在 properties 元素體內指定的屬性,
然后根據 properties 元素中的 resource 屬性讀取類路徑下屬性檔案,或根據 url 屬性指定的路徑讀取屬性檔案,并覆寫之前讀取過的同名屬性,
最后讀取作為方法引數傳遞的屬性,并覆寫之前讀取過的同名屬性,
因此,通過方法引數傳遞的屬性具有最高優先級,resource/url 屬性中指定的組態檔次之,最低優先級的則是 properties 元素中指定的屬性,
(本文僅作個人學習記錄用,如有紕漏敬請指正)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/505934.html
標籤:Java
上一篇:面試官:@Autowired, @Resource, @Inject 三個注解的區別?一下懵了。。。
下一篇:day05-執行緒的應用04
