<?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大類
每一個模塊都是configuration的子元素
好比,第一個示例中使用到的environments 和mappers
每一個模塊都有各自的職責以及配置方式,重點是要理解每個模塊具體作了什麼,具體如何設置就能夠及時的翻閱官方文檔。
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的建立方法中也能夠顯式的明確的傳遞參數
簡言之,
這些配置信息數據最終是給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">
從方法能夠看得出來,環境信息也是能夠從方法傳遞的,若是傳入將會使用指定的環境
不然,將會使用默認的
在第一個示例程序中,若是使用帶有環境變量的參數的build方法,傳入存在的environment的id信息,一切都照往常通常
映射器mappers
去哪裏找咱們定義好的mapper文件?這就是映射器mappers的做用
有四種方式能夠設置
第一個爲基於類路徑的一個相對路徑,使用resource
第二個是物理路徑,使用 url
第三個是對應接口的徹底限定名,使用 class
第四個是將一個包下面全部的所有註冊,使用 name
無論使用哪一種方式形式都是下面的形式,
指定符號爲resource、url、class、name
<mappers>
<mapper 指定符號="指定符號對應格式的字符串"/>
......
</mappers>
settings
設置信息是Mybatis的核心調整參數,上面的數據庫鏈接信息是屬於必備的基礎信息,而settings的配置項目則側重於細節,行爲的調整
一個很直觀的例子就是音樂播放器的音效調整
若是不對這些項目進行設置,通常都有一個默認的值,能夠認爲是軟件的推薦設置,音樂播放器也能夠徹底正常的進行工做,不會由於未設置而沒法運行或者出現問題。
可是,若是進行設置,這些設置項目可能會對你的音質音效產生很大的影響。
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{...}
若是一個具備必定規模的項目,多人開發每一個人都指定別名,不知道這究竟是好事仍是壞事?
對於一些內建的類型也創建了相應的別名結構,能夠參考官方文檔
好比:
類型處理 typeHandlers
類型處理器儘管平時老是用不到,可是卻無時無刻再也不被使用
不管是 MyBatis 在預處理語句(PreparedStatement)中設置一個參數時,仍是從結果集中取出一個值時, 都會用類型處理器將獲取的值以合適的方式轉換成 Java 類型。
由於Mybatis內置了默認的類型處理器,不少時候咱們並不須要對他進行處理
在JDBC中對於一個字段咱們須要setInt 或者getString這種形式的方法對字段進行處理,在Mybatis中,這些都是自動的
Mybatis之因此可以將字段與Java類型進行對應,依靠的就是typeHandler
簡言之,能夠認爲是一箇中間層方法
好比
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映射屬於哪一個數據庫
有了數據庫的標識符,再有了每一個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方法,一個是處理默認構造方法的,另一個是處理帶參數的構造方法的
想要實現本身的對象建立工廠,能夠經過
繼承
DefaultObjectFactory
繼承了DefaultObjectFactory以後,將本身的ObjectFactory配置便可
以下圖所示
總結
以上爲Mybatis配置文件中各個模塊的簡單介紹,重在介紹模塊的功能,具體用法還須要參考官方文檔
從配置文件也能夠看得出來,Mybatis的配置條理清晰,各個模塊各司其職,並且很是的靈活
- 經過properties能夠對元素進行設置
- 經過environments對環境進行指定
- 經過mappers對映射文件進行定位
- 經過settings設置能夠對Mybatis進行高級調優
- 經過typeAliases別名能夠簡化名稱,簡捷使用
- 經過typeHandlers類型處理能夠對數據與Java類型的轉換進行高級設置
- 經過plugins插件能夠在Mybatis執行邏輯中植入邏輯功能
- 經過databaseIdProvider數據庫廠商標識符 能夠靈活應用部署多數據庫
- 經過objectFactory對象工廠能夠個性化對象的建立
以上各個模塊都是configuration的子元素,放置於configuration內
須要注意的是各個元素之間也是有順序的,有順序的,在DTD文件中能夠看到
若是順序不當是會報錯的