MyBatis 的整體架構分爲三層, 分別是基礎支持層、核心處理層和接口層,如下圖所示。
基礎支持層
反射模塊 |
該模塊對 Java 原生的反射進行了良好的封裝,提供了更加簡潔易用的 API ,方便上層使調用,並且對反射操作進行了一系列優化,例如緩存了類的元數據,提高了反射操作的性能。 |
類型轉換模塊 |
類型轉換模塊提供了兩個主要功能,一個功能是別名機制,MyBatis 爲了簡化配置文件提供了別名機制;另一個功能是實現 JDBC 類型與 Java 類型之間的轉換,該功能在爲 SQL 語句綁定實參以及映射查詢結果集時都會涉及。 |
日誌模塊 |
提供詳細的日誌輸出信息,並且能夠集成多種日誌框架,其日誌模塊的一個主要功能就是集成第三方日誌框架。 |
資源加載模塊 |
資源加載模塊主要是對類加載器進行封裝,確定類加載器的使用順序,並提供了加載類文件以及其他資源文件的功能。 |
解析器模塊 |
解析器模塊主要提供兩個功能,一個功能是對 XPath 進行封裝,爲 MyBatis 初始化時解析 mybatis-config.xml 配置文件以及映射配置文件提供支持;另一個功能是爲處理動態 SQL 語句中的佔位符提供支持。 |
數據源模塊 |
MyBatis 自身提供了相應的數據源實現,也提供了與第三方數據源集成的接口。 |
事務管理 |
MyBatis 對數據庫中的事務進行了抽象,其自身提供了相應的事務接口和簡單實現。一般在應用中,MyBatis 會與 Spring 框架集成,並由 Spring 框架管理事務。 |
緩存模塊 |
MyBatis 中提供了一級緩存和二級緩存,而這兩級緩存都是依賴於基礎支持層中的緩存模塊實現的。MyBatis 中自帶的這兩級緩存與 MyBatis 以及整個應用是運行在同一個 JVM 中的,共享同一塊堆內存。如果這兩級緩存中的數據量較大, 則可能影響系統中其他功能的運行,所以當需要緩存大量數據時,優先考慮使用 Redis 、Memcache 等緩存產品。 |
Binding 模塊 |
在調用 SqlSession 相應方法執行數據庫操作時,需要指定映射文件中定義的 SQL 節點,如果出現拼寫錯誤,我們只能在運行時才能發現相應的異常。爲了儘早發現這種錯誤,MyBatis 通過 Binding 模塊將用戶自定義的 Mapper 接口與映射配置文件關聯起來,系統可以通過調用自定義 Mapper 接口中的方法執行相應的SQL 語句完成數據庫操作,從而避免上述問題。
需要注意的是,開發人員無須編寫自定義 Mapper 接口的實現,MyBatis 會自動爲其創建動態代理對象。 |
核心處理層
在覈心處理層中實現了 MyBatis 的核心處理流程,其中包括 MyBatis 的初始化以及完成一次數據庫操作涉及的全部流程。
配置解析 |
在 MyBatis 初始化過程中,會加載 mybatis-config.xml 配置文件、映射配置文件以及 Mapper 接口中的註解信息,解析後的配置信息會形成相應的對象並保存到 Configuration 對象中。之後,利用該 Configuration 對象創建 SqlSessionFactory 對象。待 MyBatis 初始化之後,開發人員可以通過初始化得到 SqlSessionFactory 創建 SqlSession 對象並完成數據庫操作。
|
SOL 解析與 scripting 模塊 |
拼湊 SQL 語句是一件煩瑣且易出錯的過程,爲了將開發人員從這項枯燥無趣的工作中解脫出來,MyBatis 實現動態 SQL 語句的功能,提供了多種動態 SQL 語句對應的節點,例如,<where> 節點、<if> 節點、<foreach> 節點等。通過這些節點的組合使用,開發人員可以寫出幾乎滿足所有需求的動態 SQL 語句。
MyBatis 中的 scripting 模塊會根據用戶傳入的實參,解析映射文件中定義的動態 SQL 節點,並形成數據庫可執行的 SQL 語句。之後會處理 SQL 語句中的佔位符,綁定用戶傳入的實參。
|
SQL 執行 |
SQL 語句的執行涉及多個組件,其中比較重要的是 Executor 、StatementHandler 、ParameterHandler 和 ResultSetHandler。Executor 主要負責維護一級緩存和二級緩存,並提供事務管理的相關操作,它會將數據庫相關操作委託給 StatementHandler 完成。StatementHandler 首先通過 ParameterHandler 完成 SQL 語句的實參綁定;然後通過 java.sql.Statement 對象執行 SQL 語句並得到結果集;最後通過 ResultSetHandler 完成結果集的映射,得到結果對象並返回。
|
插件 |
用戶可以通過添加自定義插件的方式對 MyBatis 進行擴展。用戶自定義插件也可以改變 MyBatis 的默認行爲,例如,我們可以攔截 SQL 語句並對其進行重寫。由於用戶自定義插件會影響 MyBatis 的核心行爲,在使用自定義插件之前,開發人員需要了解 MyBatis 內部的原理,這樣才能編寫出安全、高效的插件。 |
下圖展示了 MyBatis 執行一條 SQL 語句的大致過程。
接口層
接口層相對簡單,其核心是 SqlSession 接口,該接口中定義了 MyBatis 暴露給應用程序調用的 API,也就是上層應用與 MyBatis 交互的橋樑。接口層在接收到調用請求時,會調用核心處理層的相應模塊來完成具體的數據庫操作。
可以通過 MyBatis 源碼的目錄結構查看各個模塊的具體實現,目錄結構如下圖所示。
封裝的很清晰,基本是一個模塊一個 package。
MyBatis 源碼篇