Mybatis配置信息淺析 MyBatis簡介(二)


官方文檔入門篇中有明確說明
每個基於 MyBatis 的應用都是以一個 SqlSessionFactory 的實例為中心的。
SqlSessionFactory 的實例可以通過 SqlSessionFactoryBuilder 獲得。
而 SqlSessionFactoryBuilder 則可以從 XML 配置文件或一個預先定制的 Configuration 的實例構建出 SqlSessionFactory 的實例。
配置文件是Mybatis應用的核心之一(另一個核心為SQL映射)

所以配置文件的根元素為Configuration,以下為一個空的配置文件結構
<?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>



</configuration>

總覽

Mybatis的配置模塊主要分為9大類
image_5c5167af_3e08
每個模塊都是configuration的子元素
比如,第一個示例中使用到的environments 和mappers
image_5c5167af_31c7
每個模塊都有各自的職責以及配置方式,重點是要理解每一個模塊具體做了什么,具體如何設置就可以及時的翻閱官方文檔。

properties

properties與其他地方我們平時說的properties文件並沒有什么區別,就是為了引入、設置配置信息。
<propertiesresource="org/mybatis/example/config.properties"><propertyname="username"value="dev_user"/><propertyname="password"value="F2Fa3!33TYyg"/></properties>
引入的配置信息可以在配置文件中以${變量名}的形式使用,比如
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>

......

</dataSource>
使用properties時,需要注意的就是覆蓋優先級
可以使用resource指定一個properties文件
並且還可以在properties中設置
如果重名了怎么辦?
會優先使用resource中指定的值
 
Mybatis應用的核心為SqlSessionFactory,而SqlSessionFactory又是可以通過SqlSessionFactoryBuilder獲得
這些配置信息都是為了創建SqlSessionFactory而准備的
另外SqlSessionFactoryBuilder的創建方法中也可以顯式的明確的傳遞參數
image_5c5167af_191b
簡言之, 這些配置信息數據最終是給SqlSessionFactoryBuilder用來創建SqlSessionFactory的
顯然如果此處顯式的傳遞進入properties對象,那么則使用properties中的
  • 在 properties 元素體內指定的屬性首先被讀取。
  • 然后根據 properties 元素中的 resource 屬性讀取類路徑下屬性文件或根據 url 屬性指定的路徑讀取屬性文件,並覆蓋已讀取的同名屬性。
  • 最后讀取作為方法參數傳遞的屬性,並覆蓋已讀取的同名屬性。
所以對於優先級,從高到低依次為:參數傳遞,resource指定,property指定
除非特殊情況,否則,沒有必要利用這個優先級特性,可以直接使用外部的properties文件進行配置即可,全部安置於一個文件中,便於維護。

環境配置environments

MyBatis 可以配置成適應多種環境,也就是說你可以配置N個環境,然后選擇其一使用。
比如開發、測試和生產環境需要有不同的配置
盡管可以配置多個環境,但是每個 SqlSessionFactory 實例只能選擇其一
<environmentsdefault="development"><environmentid="development"><transactionManagertype="JDBC"><propertyname="..."value="..."/></transactionManager><dataSourcetype="POOLED"><propertyname="driver"value="${driver}"/><propertyname="url"value="${url}"/><propertyname="username"value="${username}"/><propertyname="password"value="${password}"/></dataSource></environment></environments>

 

注意點:
每個environment都有一個ID
environments中有一個default值<environments default="development">
 
從方法可以看得出來,環境信息也是可以從方法傳遞的,如果傳入將會使用指定的環境
否則,將會使用默認的
image_5c5167af_3998
 
在第一個示例程序中,如果使用帶有環境變量的參數的build方法,傳入存在的environment的id信息,一切都照往常一般
image_5c5167af_3a23

映射器mappers

去哪里找我們定義好的mapper文件?這就是映射器mappers的作用
 
有四種方式可以設置
第一個為基於類路徑的一個相對路徑,使用resource
第二個是物理路徑,使用 url
第三個是對應接口的完全限定名,使用 class
第四個是將一個包下面所有的全部注冊,使用 name
image_5c5167af_2231
不管使用哪種方式形式都是下面的形式, 指定符號為resource、url、class、name
<mappers>
<mapper 指定符號="指定符號對應格式的字符串"/>

......

</mappers>

settings

設置信息是Mybatis的核心調整參數,上面的數據庫連接信息是屬於必備的基礎信息,而settings的配置項目則側重於細節,行為的調整
一個很直觀的例子就是音樂播放器的音效調整
image_5c5167b0_3de9
如果不對這些項目進行設置,一般都有一個默認的值,可以認為是軟件的推薦設置,音樂播放器也可以完全正常的進行工作,不會因為未設置而無法運行或者出現問題。 
但是,如果進行設置,這些設置項目可能會對你的音質音效產生很大的影響。
Mybatis的settings選項中的各個參數就非常類似音樂播放器中音效的設置。
比如
cacheEnabled
表示:全局地開啟或關閉配置文件中的所有映射器已經配置的任何緩存。 
值為 true或者false ,默認值為true
 
對於所有的項目官方文檔中均有明確的說明,使用時務必參照文檔

別名 typeAliases

別名類似於數據庫查詢的別名,只是一個名字,僅此而已。
alias后面是別名,type是完全限定名
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>

......

</typeAliases>

 

他只和 XML 配置有關,存在的意義僅在於用來減少類完全限定名的冗余
可以使用上面的方式逐個指定
還可以指定一個包,這樣的話包下面所有的類將會有自動的別名,會使用 Bean 的首字母小寫的非限定類名來作為它的別名
比如 domain.blog.Author 的別名為 author;若有注解,則別名為其注解值。看下面的例子:
@Alias("author")publicclassAuthor{...}

 

如果一個具有一定規模的項目,多人開發每個人都指定別名,不知道這到底是好事還是壞事?
 
對於一些內建的類型也建立了相應的別名結構,可以參考官方文檔
比如:
別名        映射的類型
_byte        byte  

類型處理 typeHandlers

類型處理器盡管平時總是用不到,但是卻無時無刻不再被使用
無論是 MyBatis 在預處理語句(PreparedStatement)中設置一個參數時,還是從結果集中取出一個值時, 都會用類型處理器將獲取的值以合適的方式轉換成 Java 類型。
因為Mybatis內置了默認的類型處理器,很多時候我們並不需要對他進行處理
在JDBC中對於一個字段我們需要setInt 或者getString這種形式的方法對字段進行處理,在Mybatis中,這些都是自動的
Mybatis之所以能夠將字段與Java類型進行對應,依靠的就是typeHandler
簡言之,可以認為是一個中間層方法
image_5c5167b0_7c4a
比如
IntegerTypeHandler,Java類型為java.lang.Integer, int,數據庫兼容 NUMERIC 或 INTEGER
細節此處不介紹,簡單說就是:當遇到Java Integer類型的數據時,就調用IntegerTypeHandler,這個類型處理器就相當於完成了setInt的工作
Mybatis內置了很多的類型處理器,所以通常我們並不需要做什么,Mybatis總是能夠將類型與字段進行正確的映射
當需要更高級深層的處理時,可以考慮自定義typeHandler,他就是字段與Java類型之間的一個轉接頭

插件  plugins

插件通常在於以可插拔的形式動態的增加功能或者配置,Mybatis的插件則是側重於在方法調用過程中,增加一些自定義的處理
MyBatis 允許你在已映射語句執行過程中的某一點進行攔截調用,默認情況下,MyBatis 允許使用插件來攔截的方法調用包括:
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
ParameterHandler (getParameterObject, setParameters)
ResultSetHandler (handleResultSets, handleOutputParameters)
StatementHandler (prepare, parameterize, batch, update, query)
 
可以這么理解,在Mybatis的整個處理過程中,有一些過程的調用中,允許用戶插入自定義的執行邏輯
假設有一個對象a,調用了對象b的方法function,允許在b方法調用前添加一定的邏輯
這含義是不是非常的類似代理呢?調用真實對象之前添加方法?
事實上插件的邏輯就是代理。
簡言之,可以認為插件就是在某些方法調用時植入邏輯。

數據庫廠商標識符  databaseIdProvider

一個項目,可能配置了不同的數據庫映射文件,比如一個項目可以使用MYSQL或者ORACLE
對於不同的數據庫,部分SQL可能會有所不同,這很正常,如何靈活的配置這兩套SQL執行方案?
在Mybatis中使用的是數據庫廠商標識符
每個數據庫都有一個名稱字符串,可以通過方法進行獲取,假設MYSQL 返回的字符串標識符為 mysql
現在我知道了目標數據庫的名稱,我如果知道哪些SQL是這個數據庫的不就好了么
那么,如何標記每個SQL都是屬於哪個數據庫的呢?
如下圖所示,每一個SQL中,有一個databaseId屬性可以設置,通過他可以配置這個SQL映射屬於哪個數據庫
image_5c5167b0_24f6
有了數據庫的標識符,再有了每個SQL的標識符,自然就可以完成匹配了
比如上面的SQL databaseId的值為“mysql”,當遇到數據庫的名稱標識符為“mysql”時,僅僅加載databaseId的值為“mysql”的映射即可。
 
但是還有一個問題:
由於通常情況下這個數據庫名稱的標識符字符串都非常長而且相同產品的不同版本會返回不同的值
所以最好通過設置屬性別名來使其變短,而且通過別名做中轉,當更換版本時,項目中不需要變更
 
所以數據庫廠商標識符的完整的用法就是借助於databaseIdProvider模塊
第一步配置需要的數據庫名稱信息
value的值為別名,name的值為所需要匹配的字符串
也就是說如果獲取到的數據庫名稱標識符中包含name中設置的值,那么當前的databaseId就是value的值
總之,value的值才是項目中使用的,name的值是需要進行匹配的
匹配鍵,使用值
<databaseIdProvidertype="DB_VENDOR"><propertyname="SQL Server"value="sqlserver"/><propertyname="DB2"value="db2"/><propertyname="Oracle"value="oracle"/></databaseIdProvider>
第二步就是配置每個SQL映射的databaseId屬性值
 
最終,如果配置了 databaseIdProvider,MyBatis 會加載不帶 databaseId 屬性和帶有匹配當前數據庫 databaseId 屬性的所有語句。  
如果同時找到帶有 databaseId 和不帶 databaseId 的相同語句,則后者會被舍棄。

對象工廠 objectFactory

MyBatis是我們僅僅專注於SQL的編寫,完成了字段到Java類型對象的轉換
既然是ORM框架,從關系型數據庫中檢索到的信息終歸是要創建對象的
在Mybatis中,使用一個對象創建工廠ObjectFactory的實例來完成
默認的對象工廠需要做的僅僅是實例化目標類,要么通過默認構造方法,要么在參數映射存在的時候通過參數構造方法來實例化。一個無參一個有參
對應代碼的話就是其中的兩個create方法,一個是處理默認構造方法的,另外一個是處理帶參數的構造方法的
image_5c5167b0_7c8a
想要實現自己的對象創建工廠,可以通過 繼承 DefaultObjectFactory
image_5c5167b0_2772
繼承了DefaultObjectFactory之后,將自己的ObjectFactory配置即可
如下圖所示
image_5c5167b0_28a1

總結

以上為Mybatis配置文件中各個模塊的簡單介紹,重在介紹模塊的功能,具體用法還需要參考官方文檔
從配置文件也可以看得出來,Mybatis的配置條理清晰,各個模塊各司其職,而且非常的靈活
  • 通過properties可以對元素進行設置
  • 通過environments對環境進行指定
  • 通過mappers對映射文件進行定位
  • 通過settings設置可以對Mybatis進行高級調優
  • 通過typeAliases別名可以簡化名稱,簡捷使用
  • 通過typeHandlers類型處理可以對數據與Java類型的轉換進行高級設置
  • 通過plugins插件可以在Mybatis執行邏輯中植入邏輯功能
  • 通過databaseIdProvider數據庫廠商標識符 可以靈活應用部署多數據庫
  • 通過objectFactory對象工廠可以個性化對象的創建
以上各個模塊都是configuration的子元素,放置於configuration內
需要注意的是各個元素之間也是有順序的,有順序的,在DTD文件中可以看到
image_5c5167b0_2d0c
如果順序不當是會報錯的
image_5c5167b0_1ed0
 


免責聲明!

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



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