> 二、使用SqlSessionFactory獲取sqlSession對象。一個SqlSession對象表明和數據庫的一次會話。java
> 三、使用SqlSession根據方法id進行操做mysql
- 若是屬性在不僅一個地方進行了配置,那麼 MyBatis 將按照下面的順序來加載: git
> 在 properties 元素體內指定的屬性首先被讀取。github
> 而後根據 properties 元素中的 resource 屬性讀取類路徑下屬性文件或根據 url 屬性指定的路徑讀取屬性文件,並覆蓋已讀取的同名屬性。spring
> 最後讀取做爲方法參數傳遞的屬性,並覆蓋已讀取的同名屬性。sql
- 類不少的狀況下,能夠批量設置別名這個包下的每個類建立一個默認的別名,就是簡單類名小寫。數據庫
- 也可使用@Alias註解爲其指定一個別名express
- 值得注意的是,MyBatis已經爲許多常見的 Java 類型內建了相應的類型別名。它們都是大小寫不敏感的,咱們在起別名的時候千萬不要佔用已有的別名。apache
- Type: DB_VENDOR編程
> 使用MyBatis提供的VendorDatabaseIdProvider解析數據庫廠商標識。也能夠實現DatabaseIdProvider接口來自定義。
- Property-name:數據庫廠商標識
- Property-value:爲標識起一個別名,方便SQL語句使用databaseId屬性引用
- DB_VENDOR
> 會經過 DatabaseMetaData#getDatabaseProductName() 返回的字符串進行設置。因爲一般狀況下這個字符串都很是長並且相同產品的不一樣版本會返回不一樣的值,因此最好經過設置屬性別名來使其變短
- MyBatis匹配規則以下:
一、若是沒有配置databaseIdProvider標籤,那麼databaseId=null
- 或者使用批量註冊: 這種方式要求SQL映射文件名必須和接口名相同而且在同一目錄下
- 主鍵生成方式
> 若數據庫支持自動生成主鍵的字段(好比 MySQL和 SQL Server),則能夠設置useGeneratedKeys=」true」,而後再把keyProperty 設置到目標屬性上。
> 而對於不支持自增型主鍵的數據庫(例如Oracle),則可使用 selectKey 子元素:selectKey 元素將會首先運行,id 會被設置,而後插入語句會被調用
- selectKey
- 參數(Parameters)傳遞
> 單個參數– 能夠接受基本類型,對象類型,集合類型的值。這種狀況MyBatis可直接使用這個參數,不須要通過任何處理。
> 多個參數– 任意多個參數,都會被MyBatis從新包裝成一個Map傳入。Map的key是param1,param2,0,1…,值就是參數的值。
> 命名參數– 爲參數使用@Param起一個名字,MyBatis就會將這些參數封裝進map中,key就是咱們本身指定的名字
> POJO– 當這些參數屬於咱們業務POJO時,咱們直接傳遞POJO
> Map– 咱們也能夠封裝多個參數爲map,直接傳遞
- 參數處理
> 參數也能夠指定一個特殊的數據類型:
> javaType 一般能夠從參數對象中來去肯定
- select元素
> Select元素來定義查詢操做。
> Id:惟一標識符。– 用來引用這條語句,須要和接口的方法名一致
> parameterType:參數類型。– 能夠不傳,MyBatis會根據TypeHandler自動推斷
> resultType:返回值類型。– 別名或者全類名,若是返回的是集合,定義集合中元素的類型。不能和resultMap同時使用
- 自動映射:
一、全局setting設置
> autoMappingBehavior默認是PARTIAL,開啓自動映射的功能。惟一的要求是列名和javaBean屬性名一致
> 若是autoMappingBehavior設置爲null則會取消自動映射
> 數據庫字段命名規範,POJO屬性符合駝峯命名法,如A_COLUMNaColumn,咱們能夠開啓自動駝峯命名規則映射功能,mapUnderscoreToCamelCase=true。
二、自定義resultMap,實現高級結果集映射。
- resultMap
> constructor
>> 類在實例化時, 用來注入結果到構造方法中
>> idArg - ID 參數; 標記結果做爲 ID 能夠幫助提升總體效能
>> arg - 注入到構造方法的一個普通結果
> id – 一個 ID 結果; 標記結果做爲 ID 能夠幫助提升總體效能
> result – 注入到字段或 JavaBean 屬性的普通結果
> association
>> 一個複雜的類型關聯;許多結果將包成這種類型
>> 嵌入結果映射 – 結果映射自身的關聯,或者參考一個
> collection
>> 複雜類型的集
>> 嵌入結果映射 – 結果映射自身的集,或者參考一個
> discriminator
>> 使用結果值來決定使用哪一個結果映射
>> case – 基於某些值的結果映射:嵌入結果映射 – 這種情形結果也映射它自己,所以能夠包含不少相同的元素,或者它能夠參照一個外部的結果映射。
- id & result
> id 和 result 映射一個單獨列的值到簡單數據類型(字符串,整型,雙精度浮點數,日期等)的屬性或字段。
- association
> 複雜對象映射
> POJO中的屬性可能會是一個對象
> 咱們可使用聯合查詢,並以級聯屬性的方式封裝對象。
> 使用association標籤訂義對象的封裝規則
> association-嵌套結果集
> association-分段查詢
>> select:調用目標的方法查詢當前屬性的值
>> column:將指定列的值傳入目標方法
> association-分段查詢&延遲加載::開啓延遲加載和屬性按需加載
> 舊版本的MyBatis須要額外的支持包: asm-3.3.1.ja、 cglib-2.2.2.jar
- Collection-集合類型&嵌套結果集
- Collection-分步查詢&延遲加載
- 擴展-多列值封裝map傳遞
> 分步查詢的時候經過column指定,將對應的列的數據傳遞過去,咱們有時須要傳遞多列數據。
> 使用{key1=column1,key2=column2…}的形式
- association或者collection標籤的fetchType=eager/lazy能夠覆蓋全局的延遲加載策略,指定當即加載(eager)或者延遲加載(lazy)
- choose (when, otherwise)
- trim (where, set)
> where
> set
> trim
- foreach:動態 SQL 的另一個經常使用的必要操做是須要對一個集合進行遍歷,一般是在構建 IN 條件語句的時候。
> 當迭代列表、集合等可迭代對象或者數組時– index是當前迭代的次數,item的值是本次迭代獲取的元素
> 當使用字典(或者Map.Entry對象的集合)時– index是鍵,item是值
- bind
> bind 元素能夠從 OGNL 表達式中建立一個變量並將其綁定到上下文。好比:
- Multi-db vendor support
> 若在 mybatis 配置文件中配置了 databaseIdProvider , 則可使用 「_databaseId」變量,這樣就能夠根據不一樣的數據庫廠商構建特定的語句
- OGNL( Object Graph Navigation Language )對象圖導航語言,這是一種強大的表達式語言,經過它能夠很是方便的來操做對象屬性。 相似於咱們的EL,SpEL等
> 一級緩存演示&失效狀況
>> 同一次會話期間只要查詢過的數據都會保存在當前SqlSession的一個Map中、 key:hashCode+查詢的SqlId+編寫的sql查詢語句+參數
>> 一級緩存失效的四種狀況
一、不一樣的SqlSession對應不一樣的一級緩存
二、同一個SqlSession可是查詢條件不一樣
三、同一個SqlSession兩次查詢期間執行了任何一次增刪改操做
四、同一個SqlSession兩次查詢期間手動清空了緩存
> 二級緩存
>> 二級緩存(second level cache),全局做用域緩存
>> 二級緩存默認不開啓,須要手動配置
>> MyBatis提供二級緩存的接口以及實現,緩存實現要求POJO實現Serializable接口
>> 二級緩存在 SqlSession 關閉或提交以後纔會生效
>> 使用步驟:
一、全局配置文件中開啓二級緩存 <setting name="cacheEnabled" value="true"/>
二、須要使用二級緩存的映射文件處使用cache配置緩存 <cache />
三、注意:POJO須要實現Serializable接口
- 緩存相關屬性
> eviction=「FIFO」:緩存回收策略:
>> LRU – 最近最少使用的:移除最長時間不被使用的對象
>> FIFO – 先進先出:按對象進入緩存的順序來移除它們。
>> SOFT – 軟引用:移除基於垃圾回收器狀態和軟引用規則的對象。
>> WEAK – 弱引用:更積極地移除基於垃圾收集器狀態和弱引用規則的對象
>> 默認的是 LRU。
> flushInterval:刷新間隔,單位毫秒
>> 默認狀況是不設置,也就是沒有刷新間隔,緩存僅僅調用語句時刷新
> size:引用數目,正整數
>> 表明緩存最多能夠存儲多少個對象,太大容易致使內存溢出
> readOnly:只讀,true/false
>> true:只讀緩存;會給全部調用者返回緩存對象的相同實例。所以這些對象不能被修改。這提供了很重要的性能優點。
>> false:讀寫緩存;會返回緩存對象的拷貝(經過序列化)。這會慢一些,可是安全,所以默認是 false。
- 緩存有關設置
一、全局setting的cacheEnable: 配置二級緩存的開關。一級緩存一直是打開的。
二、select標籤的useCache屬性: 配置這個select是否使用二級緩存。一級緩存一直是使用的
三、sql標籤的flushCache屬性: 增刪改默認flushCache=true。sql執行之後,會同時清空一級和二級緩存。查詢默認flushCache=false。
四、sqlSession.clearCache(): 只是用來清除一級緩存。
五、當在某一個做用域 (一級緩存Session/二級緩存Namespaces) 進行了 C/U/D 操做後,默認該做用域下全部 select 中的緩存將被clear。
- 第三方緩存整合
> EhCache 是一個純Java的進程內緩存框架,具備快速、精幹等特色,是Hibernate中默認的CacheProvider。
> MyBatis定義了Cache接口方便咱們進行自定義擴展。
> 步驟:
一、導入ehcache包,以及整合包,日誌包:ehcache-core-2.6.8.jar、mybatis-ehcache-1.0.3.jar、slf4j-api-1.6.1.jar、slf4j-log4j12-1.6.2.jar
二、編寫ehcache.xml配置文件
三、配置cache標籤 <cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
> 參照緩存:若想在命名空間中共享相同的緩存配置和實例。可使用 cache-ref 元素來引用另一個緩存。
> Context標籤
>> targetRuntime=「MyBatis3「能夠生成帶條件的增刪改查
>> targetRuntime=「MyBatis3Simple「能夠生成基本的增刪改查若是再次生成,建議將以前生成的數據刪除,避免xml向後追加內容出現的問題。
- MBG配置文件
- 測試查詢:QBC風格的帶條件查詢
2)、在全局配置文件中註冊插件
- 插件原理
1)、按照插件註解聲明,按照插件配置順序調用插件plugin方法,生成被攔截對象的動態代理
2)、多個插件依次生成目標對象的代理對象,層層包裹,先聲明的先包裹;造成代理鏈
3)、目標方法執行時依次從外到內執行插件的intercept方法。
4)、多個插件狀況下,咱們每每須要在某個插件中分離出目標對象。能夠藉助MyBatis提供的SystemMetaObject類來進行獲取最後一層的h以及target屬性的值
- Interceptor接口
> Intercept:攔截目標方法執行
> plugin:生成動態代理對象,可使用MyBatis提供的Plugin類的wrap方法
> setProperties:注入插件配置時設置的屬性
> 咱們能夠對照官方文檔的說明,快速的使用插件
> 使用步驟:
一、導入相關包pagehelper-x.x.x.jar 和 jsqlparser-0.9.5.jar。
二、在MyBatis全局配置文件中配置分頁插件。
三、使用PageHelper提供的方法進行分頁
四、可使用更強大的PageInfo封裝返回結果
- 批量操做
> 默認的 openSession() 方法沒有參數,它會建立有以下特性的:
>> 會開啓一個事務(也就是不自動提交)
>> 鏈接對象會從由活動環境配置的數據源實例獲得。
>> 事務隔離級別將會使用驅動或數據源的默認設置。
>> 預處理語句不會被複用,也不會批量處理更新。
> openSession 方法的 ExecutorType 類型的參數,枚舉類型:
>> ExecutorType.SIMPLE: 這個執行器類型不作特殊的事情(這是默認裝配的)。它爲每一個語句的執行建立一個新的預處理語句。
>> ExecutorType.REUSE: 這個執行器類型會複用預處理語句。
>> ExecutorType.BATCH: 這個執行器會批量執行全部更新語句
> 批量操做咱們是使用MyBatis提供的BatchExecutor進行的,他的底層就是經過jdbc攢sql的方式進行的。咱們可讓他攢夠必定數量後發給數據庫一次。
> 與Spring整合中,咱們推薦,額外的配置一個能夠專門用來執行批量操做的sqlSession
> 須要用到批量操做的時候,咱們能夠注入配置的這個批量SqlSession。經過他獲取到mapper映射器進行操做。
> 注意:
一、批量操做是在session.commit()之後才發送sql語句給數據庫進行執行的
二、若是咱們想讓其提早執行,以方便後續可能的查詢操做獲取數據,咱們可使用sqlSession.flushStatements()方法,讓其直接沖刷到數據庫進行執行。
- 存儲過程
> 實際開發中,咱們一般也會寫一些存儲過程,MyBatis也支持對存儲過程的調用
> 一個最簡單的存儲過程
> 存儲過程的調用:
一、select標籤中statementType=「CALLABLE」
二、標籤體中調用語法:{call procedure_name(#{param1_info},#{param2_info})}
> 存儲過程-遊標處理
>> MyBatis對存儲過程的遊標提供了一個JdbcType=CURSOR的支持,能夠智能的把遊標讀取到的數據,映射到咱們聲明的結果集中
>> 調用實例:
- 自定義TypeHandler處理枚舉
> 咱們能夠經過自定義TypeHandler的形式來在設置參數或者取出結果集的時候自定義參數封裝策略。
> 步驟:
一、實現TypeHandler接口或者繼承BaseTypeHandler
二、使用@MappedTypes定義處理的java類型、使用@MappedJdbcTypes定義jdbcType類型
三、在自定義結果集標籤或者參數處理的時候聲明使用自定義TypeHandler進行處理或者在全局配置TypeHandler要處理的javaType
> 測試實例
>> 一個表明部門狀態的枚舉類
一、測試全局配置EnumOrdinalTypeHandler
二、測試全局配置EnumTypeHandler
三、測試參數位置設置自定義TypeHandler
> 自定義TypeHandler