1. 程式人生 > >mybatis原始碼分析1

mybatis原始碼分析1

1 原始碼結構

我們分析的mybatis原始碼version為3.4.5,mybaits-spring原始碼version為2.0.0-SNAPSHOT。先看mybatis的原始碼目錄結構,如下圖所示。

mybatis目錄結構

我們只用看src/main/java下的目錄即可。

  1. annotations:註解定義,我們知道mybatis配置可以採用XML檔案形式,也可以採用註解形式
  2. binding:主要是mapper動態代理繫結相關的類,比較重要的是MapperProxy,它是mapper動態代理的InvocationHandler,mapper的方法呼叫都是通過它的invoke方法代理的。
  3. builder:各種builder模式構造物件所使用的類,比較重要的是XMLConfigBuilder,它解析了XML檔案,並利用XML檔案中的鍵值對,設定了Configuration物件的相關變數。它是mybatis初始化階段很重要的類。
  4. cache:實現快取的類,包括cache實體和cache策略。mybatis中很多地方都是用到了cache,比如sqlSession內的一級快取,mapper內的二級快取等。
  5. cursor:遊標,在mybatis 3.4.0中,新增了返回值為遊標cursor的方法,如sqlSession的selectCursor。遊標的優點在於,當查詢大量資料時,不需要一次性將所有資料得到,可以利用遊標來逐個或分批處理,從而大大減少記憶體佔用。mybatis的預設cursor實現類為DefaultCursor。
  6. dataSource:資料來源,描述了資料庫資訊,如username password等。建立資料庫環境environment時配置資料來源dataSource。dataSource又分為JNDI,pooled和unPooled。pooled利用物件池來管理物件的建立和銷燬,可以大大減少物件的建立和銷燬次數,從而減少對系統資源的佔用,典型的享元模式
  7. exceptions:異常類
  8. executor:mybatis執行階段最重要的類,它是執行排程器,由他來排程StatementHandler ParameterHandler ResultSetHandler的執行。SqlSession的select update等讀寫資料庫的方法都是通過代理模式,由Executor來完成的。它有SimpleExecutor BatchExecutor ReuseExecutor三個實現,他們共同的基類是BaseExecutor。後面講解mybatis讀寫資料庫的流程時會重點講解。
  9. io:輸入輸出類,如資源管理類Resource,管理資源的輸入輸出流。
  10. jdbc:對JDBC的一些簡單封裝,適配mybatis。如sqlRunner,利用jdbc的讀寫資料庫的方法來操作資料庫。
  11. lang:java語言相關的類,目前只有@UsesJava7 @UsesJava8兩個註解,不用去管他們
  12. logging:log日誌類,有Log4jImpl,Slf4jImpl等對log4j和slf4j的簡單封裝後的日誌實現類等。
  13. mapping:比較複雜,解析資料庫對映mapper。有mapper.xml和註解兩種方式。這裡面的類比較多,也比較複雜,我們後面 講解mybatis初始化和執行的幾個章節,都會詳細講解其中關鍵的類。
  14. parsing:檔案解析用到的類,比較底層,一般不用特別去care。如解析XML用到的XPathParser.
  15. plugin: 外掛,mybatis一個比較強大的功能在於,可以利用動態代理來攔截mybatis的一些預設流程,從而實現使用者自定義。比如mybatis執行階段四大元件Executor StatementHandler ParameterHandler ResultSetHandler等都可以由使用者自定義外掛來實現。
  16. reflection:反射用到的類,mybatis很多地方都是用了反射,畢竟Java反射使得程式碼靈活度大大提高。mapper介面,plugin,sqlSessionTemplete都是使用動態代理生成代理物件,來執行相關方法的。
  17. scripting:指令碼語言解析相關的類,不用care
  18. session:mybatis初始化和執行階段最重要的類都在這兒,它們是mybatis的門面,和使用者打交道最多。比較關鍵的為SqlSession,SqlSessionFactory,Configuration。後面mybatis初始化和執行階段都會一一講解。
  19. transaction:事務,有JDBC和MANAGED兩種,後面會詳細講解。
  20. type:mybatis內建的typeHandler,用來做資料庫和Java類的轉換,比如varchar到String

這其中比較重要的包為executor mapping和session,我們後面詳細分析mybatis執行流程時,會詳細講解。

mybatis-spring是mybatis團隊開發的,讓mybatis在Spring容器中執行的框架。主要解決了SqlSessionFactory和sqlSession在Spring容器中注入的問題。後面我們會分兩個章節詳細講解。它的原始碼目錄結構為

mybatis-spring目錄結構

我們分析幾個比較重要的包和類。

  1. annotation:註解定義
  2. config:配置資訊處理,主要是mapper配置資訊的處理
  3. mapper:mybatis資料庫操作對映檔案相關的處理
  4. transaction:事務
  5. SqlSessionFactoryBean:工廠bean,其getObject()方法建立SqlSessionFactory物件,並注入容器中。
  6. SqlSessionTemplate:SqlSession實現類,解決了sqlSession執行緒不安全問題,可以由容器注入bean。

2 重要模組

mybatis原始碼十分複雜,滿滿的都是精巧的構思和優良的設計模式。我們會按照mybatis的各個模組,分6篇章節來詳細講解。

  • mybatis初始化和sqlSessionFactory的建立:mybatis的初始化階段,其實也就是sqlSessionFactory建立的階段。讀取並解析XML配置檔案,將其中的鍵值對設定到configuration的相關變數中,並利用初始化好的configuration物件來建立DefaultSqlSessionFactory。詳見 mybatis原始碼分析2 - SqlSessionFactory的建立

  • sqlSession的建立: mybatis讀寫資料庫,都是通過sqlSession物件來完成的。sqlSession的建立,由其工廠類sqlSessionFactory通過openSession()來完成。詳見mybatis原始碼分析3 - sqlSession的建立

  • sqlSession讀寫資料庫:sqlSession讀寫資料庫有兩種方式,一是通過select update等方法,直接進行CRUD操作。二是先getMapper獲取mapper介面動態代理,再呼叫使用者定義在mapper介面中的方法來讀寫資料庫。相比較而言,mapper方式更靈活且更健壯,豐富了使用者操作的同時,還降低了出錯的概率。mybatis也是推薦我們使用mapper方式。但mapper方式其實只是對select update等方法的一層封裝,最終還是通過select update等方法來完成的。故我們需要先了解select的執行原理。詳見mybatis原始碼分析4 - sqlSession讀寫資料庫完全解析

  • mapper方式讀寫資料庫:mybatis推薦使用mapper方式來讀寫資料庫。mapper方式下,我們先通過getMapper()方法獲取mapper介面動態代理,然後由代理執行定義在mapper介面中的相關方法。這兩個過程是如何實現的呢,詳見 mybatis原始碼分析5 - mapper讀寫資料庫完全解析

  • mybatis-spring容器初始化:mybatis不是一個單獨的框架,我們經常要結合Spring,在Spring容器中執行mybatis,這樣才能利用Spring強大的IOC和AOP功能。mybatis團隊創作了mybatis-spring框架,來讓mybatis在Spring容器中執行。mybatis-spring的初始化,其實就是Spring容器注入sqlSessionFactory單例的過程,那麼容器是如何注入的呢,詳見mybatis原始碼分析6 - mybatis-spring容器初始化

  • mybatis-spring讀寫資料庫:sqlSessionFactory由Spring容器注入後,就可以建立sqlSession並操作資料庫了。sqlSession是執行緒不安全的,沒法直接由容器注入。那麼能不能解決這一問題呢。mybatis-spring框架給出了優秀的解決方案:sqlSessionTemplete。它是一個執行緒安全的sqlSession實現類,可以由Spring容器來注入。那麼它是如何建立的呢,又是如何解決執行緒不安全問題的呢,詳見 mybatis原始碼分析7 - mybatis-spring讀寫資料庫全過程

分析mybatis原始碼,一方面能讓我們詳細瞭解mybatis底層執行機制,加深對mybatis各項特性的理解,在平時使用中做到遊刃有餘。另一方面,我覺得更重要的是,學習mybatis的精巧的框架構思和優良的設計模式,在我們自己設計架構時,這些都是很值得學習和借鑑的。