Mybatis-XML配置文件
我們在使用Mybatis框架的時候,一開始就需要先把它的配置文件寫好,雖然它的名字可以爲任意值,但是官方建議我們使用mybatis-config.xml
命名,關於該配置文件中的配置,有如下標籤:
- 屬性(properties)
- 設置(settings)
- 類型別名(typeAliases)
- 類型處理器(typeHandlers)
- 對象工廠(objectFactory)
- 插件(plugins)
- 環境配置(environments)
- 數據庫廠商識別(databaseIdProvider)
- 映射器(mappers)
以上都是Mybatis配置文件中的相關配置標籤,我們在Mybatis的配置文件中使用它們也不能亂用,特別是順序,我們要按照以上順序在配置文件中定義自己需要的配置,一般智能IDE都會有提示,使用記事本手撕代碼的讀者可要多多注意,雖然看起來較爲複雜,但是我們實際使用的也不多,下面展示博主認爲常用的一些:
屬性(properties)
這個標籤主要用於從外部引入某些屬性的值,我們以前使用原生JDBC的代碼連接數據庫通常都是將數據庫的連接信息用一個properties文件將其存儲,讓程序來讀取配置文件,從而獲得其中對應的屬性值,這裏的properties也可以理解爲這個作用。
db.properties:
mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/mybatis?useSSl=true&useUnicode=true&characterEncoding=UTF-8
mysql.username=root
mysql.password=123456
在Mybatis的配置文件中引入上面這個db。properties配置文件中的值。
<!-- properties標籤用於指定我們需要從外部加載配置文件 -->
<!-- resource:指定我們加載properties文件的類路徑(常用) -->
<!-- url:指定我們加載properties文件的完全限定路徑 -->
<!-- resource和url我們選擇一個使用即可 -->
<properties resource="db.properties">
<!-- 這裏面的子標籤表示可以在引入外部配置文件的基礎上再添加屬性 -->
<!-- name:屬性名 -->
<!-- value:屬性值 -->
<property name="mysql.username" value="Ara_Hu"/>
</properties>
引入的目的就是爲了得到其中的值,我們引入的是關於數據庫連接的一些參數,那麼在Mybatis的配置文件中想要得到其中的值,採用${屬性名}
獲取,舉例如下:
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
這裏值得注意的地方就是我們在外部配置文件db.properties和properties的標籤中都設置了一個同名的屬性mysql.username
,但是其中的值不一致,Mybatis將會按照下面的順序來加載:
- 在properties元素內指定的屬性會首先被讀取。
- 然後根據properties元素中的resource屬性讀取類路徑下屬性文件或者根據url屬性指定的路徑讀取屬性文件,這個動作會覆蓋已經讀取的同名屬性。
- 最後去讀作爲方法參數傳遞的屬性,這個動作會覆蓋已經讀取的同名屬性。
由此看來,通過方法參數傳遞的屬性具有最高的優先級,其次是resource/url屬性中指定的配置文件,最低的優先級是properties屬性中指定的屬性。
設置(settings)
該標籤是用於設置Mybatis運行時的行爲。
<!-- 用於設置Mybatis運行時的行爲 -->
<settings>
<!-- 用於具體設置某種行爲 -->
<!-- name:行爲名稱 -->
<!-- value:行爲值 -->
<setting name="" value=""/>
</settings>
它的行爲值包含如下:
name | value | 默認 | 描述 |
---|---|---|---|
cacheEnabled | true、false | true | 全局的開啓或關閉配置文件中的所有映射器已經配置的任何緩存 |
lazyLoadingEnabled | true、false | false | 延遲加載的全局開關,開啓時,所有的關聯對象都會延遲加載。特定關聯關係中可通過設置fetchType來覆蓋該設置 |
aggressiveLazyLoading | true、false | false | 當開啓時,任何方法的調用都會加載該對象的所有屬性。 否則,每個屬性會按需加載 |
multipleResultSetsEnabled | true、false | true | 是否允許單一語句返回多結果集(需要驅動支持) |
useColumnLabel | true、false | true | 使用列標籤代替列名。不同的驅動在這方面會有不同的表現,具體可參考相關驅動文檔或通過測試這兩種不同的模式來觀察所用驅動的結果 |
useGeneratedKeys | true、false | false | 允許 JDBC 支持自動生成主鍵,需要驅動支持。 如果設置爲 true 則這個設置強制使用自動生成主鍵,儘管一些驅動不能支持但仍可正常工作 |
autoMappingBehavior | NONE, PARTIAL, FULL | PARTIAL | 指定 MyBatis 應如何自動映射列到字段或屬性。 NONE 表示取消自動映射;PARTIAL 只會自動映射沒有定義嵌套結果集映射的結果集。 FULL 會自動映射任意複雜的結果集(無論是否嵌套) |
autoMappingUnknownColumnBehavior | NONE, WARNING, FAILING | NONE | 指定發現自動映射目標未知列(或者未知屬性類型)的行爲。NONE: 不做任何反應,WARNING: 輸出提醒日誌 ('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior’的日誌等級必須設置爲 WARN),FAILING: 映射失敗 (拋出 SqlSessionException) |
defaultExecutorType | SIMPLE,REUSE,BATCH | SIMPLE | 配置默認的執行器。SIMPLE 就是普通的執行器;REUSE 執行器會重用預處理語句(prepared statements); BATCH 執行器將重用語句並執行批量更新 |
defaultStatementTimeout | 任意正整數 | null | 設置超時時間,它決定驅動等待數據庫響應的秒數 |
defaultFetchSize | 任意正整數 | null | 爲驅動的結果集獲取數量(fetchSize)設置一個提示值。此參數只可以在查詢設置中被覆蓋 |
safeRowBoundsEnabled | true,false | false | 允許在嵌套語句中使用分頁(RowBounds)。如果允許使用則設置爲 false |
safeResultHandlerEnabled | true,false | true | 允許在嵌套語句中使用分頁(ResultHandler)。如果允許使用則設置爲 false |
mapUnderscoreToCamelCase | true,false | false | 是否開啓自動駝峯命名規則(camel case)映射(從經典數據庫列名 A_COLUMN 到經典 Java 屬性名 aColumn 的類似映射) |
localCacheScope | SESSION,STATEMENT | SESSION | MyBatis 利用本地緩存機制(Local Cache)防止循環引用(circular references)和加速重複嵌套查詢。 默認值爲 SESSION,這種情況下會緩存一個會話中執行的所有查詢。 若設置值爲 STATEMENT,本地會話僅用在語句執行上,對相同 SqlSession 的不同調用將不會共享數據 |
jdbcTypeForNull | JdbcType 常量,常用值:NULL, VARCHAR 或 OTHER | OTHER | 當沒有爲參數提供特定的 JDBC 類型時,爲空值指定 JDBC 類型。 某些驅動需要指定列的 JDBC 類型,多數情況直接用一般類型即可,比如 NULL、VARCHAR 或 OTHER |
lazyLoadTriggerMethods | 用逗號分隔的方法列表 | equals,clone,hashCode,toString | 指定哪個對象的方法觸發一次延遲加載 |
defaultScriptingLanguage | 一個類型別名或完全限定類名 | org.apache.ibatis.scripting.xmltags.XMLLanguageDriver | 指定動態 SQL 生成的默認語言 |
defaultEnumTypeHandler | 一個類型別名或完全限定類名 | org.apache.ibatis.type.EnumTypeHandler | 指定 Enum 使用的默認 TypeHandler |
callSettersOnNulls | true、false | false | 指定當結果集中值爲 null 的時候是否調用映射對象的 setter(map 對象時爲 put)方法,這在依賴於 Map.keySet() 或 null 值初始化的時候比較有用。注意基本類型(int、boolean 等)是不能設置成 null 的 |
returnInstanceForEmptyRow | true,false | false | 當返回行的所有列都是空時,MyBatis默認返回 null。 當開啓這個設置時,MyBatis會返回一個空實例。 請注意,它也適用於嵌套的結果集 (如集合或關聯) |
logPrefix | 任何字符串 | 未設置 | 指定 MyBatis 增加到日誌名稱的前綴 |
logImpl | SLF4J,LOG4J,LOG4J2,JDK_LOGGING,COMMONS_LOGGING,STDOUT_LOGGING,NO_LOGGING | 未設置 | 指定 MyBatis 所用日誌的具體實現,未指定時將自動查找 |
proxyFactory | CGLIB,JAVASSIST | JAVASSIST | 指定 Mybatis 創建具有延遲加載能力的對象所用到的代理工具 |
vfsImpl | 自定義 VFS 的實現的類全限定名,以逗號分隔 | 未設置 | 指定 VFS 的實現 |
useActualParamName | true,false | true | 允許使用方法簽名中的名稱作爲語句參數名稱。 爲了使用該特性,你的項目必須採用 Java 8 編譯,並且加上 -parameters 選項 |
configurationFactory | 類型別名或者全類名 | 未設置 | 指定一個提供 Configuration 實例的類。 這個被返回的 Configuration 實例用來加載被反序列化對象的延遲加載屬性值。 這個類必須包含一個簽名爲static Configuration getConfiguration() 的方法 |
這個看起來確實很多,但是我們後續會慢慢涉及到其中的一些。
類型別名(typeAliases)
typeAliases標籤就是爲Java類型設置一個短名字,它只和XML配置相關,它的出現就是爲了減少類的完全限定名的冗餘。
比如我們之前每次在持久層接口對應的xml文件中的參數值或者返回值類型,如果爲自定義的JavaBean,我們都需要加上全限定類名:
<select id="getUserList" resultType="com.ara.pojo.User">
select * from user;
</select>
<insert id="addUser" parameterType="com.ara.pojo.User">
insert into user (name, password) values (#{name},#{password});
</insert>
...
我們每次寫resultType或者parameterType都會寫這麼長一串,感覺十分的龐大冗餘,而且意義也不大,所以Mybatis提供了typeAliases標籤,讓我們爲其取別名。
<!-- 起別名使用的標籤,減少參數類型和結果集類型的冗餘 -->
<typeAliases>
<!-- 來設置具體的類型及其別名 -->
<!-- type:需要設置的全限定類名 -->
<!-- alias:分配的別名 -->
<typeAlias type="com.ara.pojo.User" alias="User" />
<!-- 直接指定一個包 -->
<!-- name:指定的包名,Mybatis會在該包下搜索需要的JavaBean -->
<package name="com.ara.pojo" />
</typeAliases>
通過直接指定包名起別名的方式,沒有在該包下JavaBean的類上指定@Alias("別名")
的時候,會默認使用JavaBean的首字母小寫的非限定類名來作爲它的別名,當然我們也可以直接在類上加註解來指定:
@Alias("user")
public class User {
...
}
如下爲Java中的一些類型別名,它們都是不區分大小寫的,注意對基本類型名稱重複採取的特殊命名風格。
別名 | 映射的Java類型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int,_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int,integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal,bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
環境配置(environments)
Mybatis可以配置多套數據庫的使用環境,這種機制十分有助於將SQL映射應用於多種數據庫之中。
雖然可以配置多個數據環境,但是每個SqlSessionFactory實例只能選擇一種數據庫環境。所以我們的項目中存在幾個數據庫,就需要幾個SqlSessionFactory實例對象。
可以通過下面的方法在創建SqlSessionFactory實例對象的時候指定數據環境。
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties);
當我們沒有配置數據指定環境的時候,會默認加載Mybatis配置文件中指定的默認數據源。
<!-- 設置數據源環境 -->
<!-- default:指定默認的數據源id -->
<environments default="mysql">
<!-- 設置一個數據源 -->
<!-- id:爲該數據源指定唯一標識Id -->
<environment id="mysql">
<!-- 配置事務管理 -->
<!-- type:聲明事務管理類型,其值有JDBC和MANAGED兩種,一般常使用JDBC -->
<!-- JDBC:這個配置就是直接使用了JDBC的提交和回滾設置,它依賴於從數據源得到的連接來管理事務作用域 -->
<!-- MANAGED:這個配置幾乎沒做什麼。它從來不提交或回滾一個連接,而是讓容器來管理事務的整個生命週期。默認情況下它會關閉連接,然而一些容器並不希望這樣,因此需要將closeConnection屬性設置爲false來阻止它默認的關閉行爲 -->
<transactionManager type="JDBC"/>
<!-- 配置數據源 -->
<!-- type:配置數據源的類型,其值有UNPOOLED POOLED和JNDI -->
<!-- UNPOOLED:表示不使用數據庫連接池,每次執行SQL時打開連接,執行完畢之後關閉連接 -->
<!-- POOLED:表示使用數據庫連接池,將連接對象放入連接池,使用時取出,用完後放回,大大提高了SQL的執行效率 -->
<!-- JNDI:這個數據源的實現是爲了能在如 EJB 或應用服務器這類容器中使用,容器可以集中或在外部配置數據源,然後放置一個JNDI上下文的引用 -->
<dataSource type="POOLED">
<!-- 爲該數據源設置參數 -->
<!-- name:設置的屬性名 -->
<!-- value:對應的屬性值 -->
<property name="" value=""/>
</dataSource>
</environment>
</environments>
對於不同的數據源,設置的參數也有所差異:
- UNPOOLED:存在如下屬性
- driver:這是 JDBC 驅動的 Java 類的完全限定名
- url:這是數據庫的JDBC URL地址
- username:登錄數據庫的用戶名
- password:登錄數據庫的密碼
- defaultTransactionIsolationLevel:默認的連接事務隔離級別
- defaultNetworkTimeout:默認網絡超時時間,毫秒值
- POOLED:在上面UNPOOLED的屬性基礎上還存在以下屬性:
- 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:這種數據源配置只需要兩個屬性
- initial_context:這個屬性用來在 InitialContext 中尋找上下文(即,initialContext.lookup(initial_context))。這是個可選屬性,如果忽略,那麼將會直接從 InitialContext 中尋找 data_source 屬性
- data_source:這是引用數據源實例位置的上下文的路徑
常用的幾乎就是POOLED了。
映射器(mappers)
mappers標籤就是用於映射我們定義的Mapper.xml文件了,就是告訴Mybatis需要到哪裏找我們編寫的Mapper.xml文件。
我們可以使用如下方式:
<!-- 告訴Mybatis我們定義的Mapper.xml文件在哪裏 -->
<mappers>
<!-- 指定資源 -->
<!-- resource:使用相對於類路徑的資源引用 -->
<!-- url:使用完全限定資源定位符(不建議使用) -->
<!-- class:使用映射器接口實現類的完全限定類名 -->
<mapper resource="com/ara/dao/UserMapper.xml" />
<!-- 指定掃描的包,將指定包中的映射器接口實現全部註冊爲映射器 -->
<!-- name:指定的包名 -->
<package name="com.ara.xxx"/>
</mappers>
當然,實際開發中還是要看業務需要,來選擇合適的配置。