JavaEE高級-MyBatis學習筆記

1、MyBatis簡介
  - MyBatis 是支持定製化 SQL、存儲過程以及高級映射的優秀的持久層框架。
  - MyBatis 避免了幾乎全部的 JDBC 代碼和手動設置參數以及獲取結果集。
  - MyBatis可使用簡單的XML或註解用於配置和原始映射,將接口和Java的POJO(Plain Old JavaObjects,普通的Java對象)映射成數據庫中的記錄.
  - MyBatis歷史:
    > 原是Apache的一個開源項目iBatis, 2010年6月這個項目由Apache Software Foundation 遷移到了Google Code,隨着開發團隊轉投Google Code旗下, iBatis3.x正式改名爲MyBatis ,
     代碼於2013年11月遷移到Github(下載地址見後)。
    > iBatis一詞來源於「internet」和「abatis」的組合,是一個基於Java的持久層框架。 iBatis提供的持久層框架包括SQL Maps和Data Access Objects(DAO)
 
爲何要使用MyBatis?
  - MyBatis是一個半自動化的持久化層框架。
  - JDBC:
    > SQL夾在Java代碼塊裏,耦合度高致使硬編碼內傷
    > 維護不易且實際開發需求中sql是有變化,頻繁修改的狀況多見
  - Hibernate和JPA:
    > 長難複雜SQL,對於Hibernate而言處理也不容易
    > 內部自動生產的SQL,不容易作特殊優化。
    > 基於全映射的全自動框架,大量字段的POJO進行部分映射時比較困難。致使數據庫性能降低。 
  - 對開發人員而言,核心sql仍是須要本身優化
  - sql和java編碼分開,功能邊界清晰,一個專一業務、一個專一數據。
 
去哪裏找MyBatis? 
  https://github.com/mybatis/mybatis-3/
 
 
2、MyBatis-HelloWorld
  - HelloWorld簡單版
    > 建立一張測試表
    > 建立對應的javaBean
    > 建立mybatis配置文件,sql映射文件
    > 測試
 
MyBatis操做數據庫
  一、建立MyBatis全局配置文件
    - MyBatis 的全局配置文件包含了影響 MyBatis 行爲甚深的設置(settings)和屬性(properties)信息、如數據庫鏈接池信息等。指導着MyBatis進行工做。咱們能夠參照官方文件的配置示例。 
  二、建立SQL映射文件
    - 映射文件的做用就至關因而定義Dao接口的實現類如何工做。這也是咱們使用MyBatis時編寫的最多的文件。
  - 測試:
    > 一、根據全局配置文件,利用SqlSessionFactoryBuilder建立SqlSessionFactory
        

    > 二、使用SqlSessionFactory獲取sqlSession對象。一個SqlSession對象表明和數據庫的一次會話。java

        

    > 三、使用SqlSession根據方法id進行操做mysql

        

 
HelloWorld-接口式編程
  - 建立一個Dao接口
  - 修改Mapper文件
  - 測試:
    > 使用SqlSession獲取映射器進行操做
      

 

SqlSession
  - SqlSession 的實例不是線程安全的,所以是不能被共享的。 
  - SqlSession每次使用完成後須要正確關閉,這個關閉操做是必須的
  - SqlSession能夠直接調用方法的id進行數據庫操做,可是咱們通常仍是推薦使用SqlSession獲取到Dao接口的代理類,執行代理對象的方法,能夠更安全的進行類型檢查操做
 
 
3、MyBatis-全局配置文件
  - MyBatis 的配置文件包含了影響 MyBatis 行爲甚深的設置(settings)和屬性(properties)信息。文檔的頂層結構以下: 
    > configuration 配置:
      >> properties 屬性
      >> settings 設置
      >> typeAliases 類型命名
      >> typeHandlers 類型處理器
      >> objectFactory 對象工廠
      >> plugins 插件
      >> environments 環境
          environment 環境變量
              transactionManager 事務管理器
              dataSource 數據源
      >> databaseIdProvider 數據庫廠商標識
      >> mappers 映射器
  - 在Eclipse中引入XML的dtd約束文件,方便編寫XML的時候有提示
 
properties屬性
   

  

  - 若是屬性在不僅一個地方進行了配置,那麼 MyBatis 將按照下面的順序來加載: git

    > 在 properties 元素體內指定的屬性首先被讀取。github

    > 而後根據 properties 元素中的 resource 屬性讀取類路徑下屬性文件或根據 url 屬性指定的路徑讀取屬性文件,並覆蓋已讀取的同名屬性。spring

    > 最後讀取做爲方法參數傳遞的屬性,並覆蓋已讀取的同名屬性。sql

 

settings設置
  - 這是 MyBatis 中極爲重要的調整設置,它們會改變MyBatis 的運行時行爲。
    

    

 

 
typeAliases別名處理器
  - 類型別名是爲 Java 類型設置一個短的名字,能夠方便咱們引用某個類。
    

  - 類不少的狀況下,能夠批量設置別名這個包下的每個類建立一個默認的別名,就是簡單類名小寫。數據庫

    

  - 也可使用@Alias註解爲其指定一個別名express

    

  - 值得注意的是,MyBatis已經爲許多常見的 Java 類型內建了相應的類型別名。它們都是大小寫不敏感的,咱們在起別名的時候千萬不要佔用已有的別名。apache

    

 

 
typeHandlers類型處理器
  - 不管是 MyBatis 在預處理語句(PreparedStatement)中設置一個參數時,仍是從結果集中取出一個值時, 都會用類型處理器將獲取的值以合適的方式轉換成 Java 類型。
    

 

日期類型的處理
  - 日期和時間的處理,JDK1.8之前一直是個頭疼的問題。咱們一般使用JSR310規範領導者StephenColebourne建立的Joda-Time來操做。1.8已經實現所有的JSR310規範了。
  - 日期時間處理上,咱們可使用MyBatis基於JSR310(Date and Time API)編寫的各類日期時間類型處理器。
  - MyBatis3.4之前的版本須要咱們手動註冊這些處理器,之後的版本都是自動註冊的
    

 

 
自定義類型處理器
  - 咱們能夠重寫類型處理器或建立本身的類型處理器來處理不支持的或非標準的類型。 
  - 步驟:
    1)、實現org.apache.ibatis.type.TypeHandler接口或者繼承org.apache.ibatis.type.BaseTypeHandler
    2)、指定其映射某個JDBC類型(可選操做)
    3)、在mybatis全局配置文件中註冊
 
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)
 
environments環境
  - MyBatis能夠配置多種環境,好比開發、測試和生產環境須要有不一樣的配置。 
  - 每種環境使用一個environment標籤進行配置並指定惟一標識符
  - 能夠經過environments標籤中的default屬性指定一個環境的標識符來快速的切換環境
  - environment-指定具體環境:
    > id:指定當前環境的惟一標識
    > transactionManager、和dataSource都必須有
      

 

transactionManager
  - type: JDBC | MANAGED | 自定義:
    > JDBC:使用了 JDBC 的提交和回滾設置,依賴於從數據源獲得的鏈接來管理事務範圍。JdbcTransactionFactory
    > MANAGED:不提交或回滾一個鏈接、讓容器來管理事務的整個生命週期(好比 JEE 應用服務器的上下文)。 ManagedTransactionFactory
    > 自定義:實現TransactionFactory接口,type=全類名/別名
 
dataSource
  - type: UNPOOLED | POOLED | JNDI | 自定義
    > UNPOOLED:不使用鏈接池,UnpooledDataSourceFactory
    > POOLED:使用鏈接池, PooledDataSourceFactory
    > JNDI: 在EJB 或應用服務器這類容器中查找指定的數據源
    > 自定義:實現DataSourceFactory接口,定義數據源的獲取方式。
  - 實際開發中咱們使用Spring管理數據源,並進行事務控制的配置來覆蓋上述配置
 
databaseIdProvider環境
  - MyBatis 能夠根據不一樣的數據庫廠商執行不一樣的語句。
    

  - Type: DB_VENDOR編程

    > 使用MyBatis提供的VendorDatabaseIdProvider解析數據庫廠商標識。也能夠實現DatabaseIdProvider接口來自定義。

  - Property-name:數據庫廠商標識

  - Property-value:爲標識起一個別名,方便SQL語句使用databaseId屬性引用

    

  - DB_VENDOR

    > 會經過 DatabaseMetaData#getDatabaseProductName() 返回的字符串進行設置。因爲一般狀況下這個字符串都很是長並且相同產品的不一樣版本會返回不一樣的值,因此最好經過設置屬性別名來使其變短 

  - MyBatis匹配規則以下:

    一、若是沒有配置databaseIdProvider標籤,那麼databaseId=null

    二、若是配置了databaseIdProvider標籤,使用標籤配置的name去匹配數據庫信息,匹配上設置databaseId=配置指定的值,不然依舊爲null
    三、若是databaseId不爲null,他只會找到配置databaseId的sql語句
    四、MyBatis 會加載不帶 databaseId 屬性和帶有匹配當前數據庫databaseId 屬性的全部語句。若是同時找到帶有 databaseId 和不帶databaseId 的相同語句,則後者會被捨棄。
 
mapper映射
  - mapper逐個註冊SQL映射文件
    

  - 或者使用批量註冊: 這種方式要求SQL映射文件名必須和接口名相同而且在同一目錄下

    

 

 

4、MyBatis-映射文件
  - 映射文件指導着MyBatis如何進行數據庫增刪改查,有着很是重要的意義;
    > cache –命名空間的二級緩存配置
    > cache-ref – 其餘命名空間緩存配置的引用。
    > resultMap – 自定義結果集映射
    > parameterMap – 已廢棄!老式風格的參數映射
    > sql –抽取可重用語句塊。
    > insert – 映射插入語句
    > update – 映射更新語句
    > delete – 映射刪除語句
    > select – 映射查詢語句
    

  - 主鍵生成方式

    > 若數據庫支持自動生成主鍵的字段(好比 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 一般能夠從參數對象中來去肯定

    > 若是 null 被看成值來傳遞,對於全部可能爲空的列,jdbcType 須要被設置
    > 對於數值類型,還能夠設置小數點後保留的位數:
    > mode 屬性容許指定 IN,OUT 或 INOUT 參數。若是參數爲 OUT 或 INOUT,參數對象屬性的真實值將會被改變,就像在獲取輸出參數時所指望的那樣。
    > 參數位置支持的屬性– javaType、jdbcType、mode、numericScale、resultMap、typeHandler、jdbcTypeName、expression
    > 實際上一般被設置的是:可能爲空的列名指定 jdbcType
    > #{key}:獲取參數的值,預編譯到SQL中。安全。
    > ${key}:獲取參數的值,拼接到SQL中。有SQL注入問題。ORDER BY ${name}

  - select元素

    > Select元素來定義查詢操做。

    > Id:惟一標識符。– 用來引用這條語句,須要和接口的方法名一致

    > parameterType:參數類型。– 能夠不傳,MyBatis會根據TypeHandler自動推斷

    > resultType:返回值類型。– 別名或者全類名,若是返回的是集合,定義集合中元素的類型。不能和resultMap同時使用

      

  - 自動映射:

    一、全局setting設置

      > autoMappingBehavior默認是PARTIAL,開啓自動映射的功能。惟一的要求是列名和javaBean屬性名一致

      > 若是autoMappingBehavior設置爲null則會取消自動映射

      > 數據庫字段命名規範,POJO屬性符合駝峯命名法,如A_COLUMNaColumn,咱們能夠開啓自動駝峯命名規則映射功能,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)

 

 

5、MyBatis-動態SQL
  - 動態 SQL是MyBatis強大特性之一。極大的簡化咱們拼裝SQL的操做。
  - 動態 SQL 元素和使用 JSTL 或其餘相似基於 XML 的文本處理器類似。
  - MyBatis 採用功能強大的基於 OGNL 的表達式來簡化操做。 if、choose (when, otherwise)、 trim (where, set)、foreach
  - if
    

  - 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等

      

 

 

6、MyBatis-緩存機制
  - MyBatis 包含一個很是強大的查詢緩存特性,它能夠很是方便地配置和定製。緩存能夠極大的提高查詢效率。
  - MyBatis系統中默認定義了兩級緩存。 
  - 一級緩存和二級緩存。 
    一、默認狀況下,只有一級緩存(SqlSession級別的緩存,也稱爲本地緩存)開啓。
    二、二級緩存須要手動開啓和配置,他是基於namespace級別的緩存。
    三、爲了提升擴展性。MyBatis定義了緩存接口Cache。咱們能夠經過實現Cache接口來自定義二級緩存
  - 一級緩存
    > 一級緩存(local cache), 即本地緩存, 做用域默認爲sqlSession。當 Session flush 或 close 後, 該Session 中的全部 Cache 將被清空。
    > 本地緩存不能被關閉, 但能夠調用 clearCache()來清空本地緩存, 或者改變緩存的做用域. 
    > 在mybatis3.1以後, 能夠配置本地緩存的做用域.在 mybatis.xml 中配置  
        

    > 一級緩存演示&失效狀況

      >> 同一次會話期間只要查詢過的數據都會保存在當前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 元素來引用另一個緩存。

        

      

 

 

7、MyBatis-Spring整合
  一、查看不一樣MyBatis版本整合Spring時使用的適配包:http://www.mybatis.org/spring/ 
  二、下載整合適配包:https://github.com/mybatis/spring/releases
  三、官方整合示例,jpetstore:https://github.com/mybatis/jpetstore-6
  - 整合關鍵配置:
    

 

 

8、MyBatis-逆向工程
  - MyBatis Generator: 
  - 簡稱MBG,是一個專門爲MyBatis框架使用者定製的代碼生成器,能夠快速的根據表生成對應的映射文件,接口,以及bean類。支持基本的增刪改查,以及QBC風格的條件查詢。可是錶鏈接、存儲過程等這些複雜sql的定義須要咱們手工編寫
  - 官方文檔地址:http://www.mybatis.org/generator/ 
  - 官方工程地址:https://github.com/mybatis/generator/releases
 
MBG使用
  - 使用步驟:  
    1)編寫MBG的配置文件(重要幾處配置)
      1)jdbcConnection配置數據庫鏈接信息
      2)javaModelGenerator配置javaBean的生成策略
      3)sqlMapGenerator 配置sql映射文件生成策略
      4)javaClientGenerator配置Mapper接口的生成策略
      5)table 配置要逆向解析的數據表
        tableName:表名
        domainObjectName:對應的javaBean名
    2)運行代碼生成器生成代碼
  - 注意:

     > Context標籤

      >> targetRuntime=「MyBatis3「能夠生成帶條件的增刪改查

      >> targetRuntime=「MyBatis3Simple「能夠生成基本的增刪改查若是再次生成,建議將以前生成的數據刪除,避免xml向後追加內容出現的問題。

  - MBG配置文件   

    <generatorConfiguration>
     <context id="DB2Tables" targetRuntime="MyBatis3">
      //數據庫鏈接信息配置
      <jdbcConnection driverClass="com.mysql.jdbc.Driver"
        connectionURL="jdbc:mysql://localhost:3306/bookstore0629"
        userId="root" password="123456">
      </jdbcConnection>
      //javaBean的生成策略
      <javaModelGenerator targetPackage="com.atguigu.bean" targetProject=".\src">
        <property name="enableSubPackages" value="true" />
        <property name="trimStrings" value="true" />
      </javaModelGenerator>
      //映射文件的生成策略
      <sqlMapGenerator targetPackage="mybatis.mapper" targetProject=".\conf">
        <property name="enableSubPackages" value="true" />
      </sqlMapGenerator>
      //dao接口java文件的生成策略
      <javaClientGenerator type="XMLMAPPER" targetPackage="com.atguigu.dao"
        targetProject=".\src">
        <property name="enableSubPackages" value="true" />
      </javaClientGenerator>
      //數據表與javaBean的映射
      <table tableName="books" domainObjectName="Book"></table>
    </context>
   </generatorConfiguration>
  
  - 生成器代碼
    

  - 測試查詢:QBC風格的帶條件查詢

    

 

  

9、MyBatis-工做原理
  

 

 
10、MyBatis-插件開發
  - MyBatis在四大對象的建立過程當中,都會有插件進行介入。插件能夠利用動態代理機制一層層的包裝目標對象,而實如今目標對象執行目標方法以前進行攔截的效果。
  - MyBatis 容許在已映射語句執行過程當中的某一點進行攔截調用。
  - 默認狀況下,MyBatis 容許使用插件來攔截的方法調用包括:
    > Executor (update, query, flushStatements, commit, rollback,getTransaction, close, isClosed) 
    > ParameterHandler (getParameterObject, setParameters) 
    > ResultSetHandler (handleResultSets, handleOutputParameters) 
    > StatementHandler (prepare, parameterize, batch, update, query) 
  - 插件開發
    > 插件開發步驟:
      1)、編寫插件實現Interceptor接口,並使用@Intercepts註解完成插件簽名
        

      2)、在全局配置文件中註冊插件

        

  - 插件原理

    1)、按照插件註解聲明,按照插件配置順序調用插件plugin方法,生成被攔截對象的動態代理

    2)、多個插件依次生成目標對象的代理對象,層層包裹,先聲明的先包裹;造成代理鏈

    3)、目標方法執行時依次從外到內執行插件的intercept方法。 

    4)、多個插件狀況下,咱們每每須要在某個插件中分離出目標對象。能夠藉助MyBatis提供的SystemMetaObject類來進行獲取最後一層的h以及target屬性的值

  - Interceptor接口

    > Intercept:攔截目標方法執行

    > plugin:生成動態代理對象,可使用MyBatis提供的Plugin類的wrap方法

    > setProperties:注入插件配置時設置的屬性

 

 

擴展:MyBatis實用場景
  - PageHelper插件進行分頁
    > PageHelper是MyBatis中很是方便的第三方分頁插件。
    > 官方文檔:https://github.com/pagehelper/MybatisPageHelper/blob/master/README_zh.md

    > 咱們能夠對照官方文檔的說明,快速的使用插件

    > 使用步驟:

      一、導入相關包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

        

相關文章
相關標籤/搜索