天天看點

MyBatis 源碼分析-項目總覽

MyBatis 源碼分析-項目總覽

1.概述

本文主要大緻介紹一下MyBatis的項目結構。引用參考資料《MyBatis技術内幕》

此外,

https://mybatis.org/mybatis-3/zh/index.html

 MyBatis官方也提供了很不錯的中文文檔。對于使用中有碰到一些問題,可以參考一下。

2.子產品劃分

MyBatis在項目子產品劃分還是很清晰的。各個子產品層次以及具體作用,如下:

子產品 層次 定義

session 接口層 提供給外部使用的接口API

scripting 核心處理層 解析映射檔案中的動态SQL節點。并形成資料庫可執行的SQL語句。

mapping 核心處理層 映射

builder 核心處理層 配置解析

executor 核心處理層 執行器子產品,串聯整個執行流程。

plugin 核心處理層 插件子產品:提供插件接口,通過自定義插件方式對MyBatis進行拓展

cursor 核心處理層 遊标子產品

reflection 基礎支援層 反射子產品:mybatis專門對反射子產品進行封裝。提供更加簡單易用的API

type 基礎支援層 類型轉換子產品:Mybatis為簡化配置提供了别名機制。提供java類型與JDBC類型轉換

logging 基礎支援層 日志子產品:主要是內建第三方日志

io 基礎支援層 資源加載子產品:對類加載器進行了封裝。确定類加載器順序,并提供加載檔案,以及其他資源的功能

datasource 基礎支援層 資料源子產品:mybatis自身提供響應的資料源實作,也提供與第三方資料內建的接口。

transaction 基礎支援層 事務管理子產品:Mybatis 對資料庫的事務進行了抽象

parsing 基礎支援層 解析器子產品:提供兩個功能:1. 對XPath進行封裝 2為處理動态sql語句中的占位符提供支援

cache 基礎支援層 緩存子產品:提供一級緩存、二級緩存。優化查詢

binding 基礎支援層 Binding子產品:将自定義的接口與映射配置檔案關聯起來。通過調用mapper接口完成資料庫執行。

exceptions 基礎支援層 異常處理

annotations 基礎支援層 注解子產品

jdbc 其他 JDBC子產品

lang 其他 Lang子產品

整體結構

整體分為三層:

接口層:定義了MyBatis暴露給應用程式調用的API。

核心處理層:實作了MyBatis的核心處理流程,包括MyBatis初始化以及完成一次資料庫操作的涉及的全部流程。

基礎支援層:為核心處理層提供了良好的基礎支撐。例如:反射、類型轉換、日志、緩存、事務等子產品。

3.1 基礎支援層

3.1.1 反射子產品

對應reflection包

Java中的反射雖然功能強大,但對大多數開發人員來說,寫出高品質的反射代碼還是有一定難度的。MyBatis 中專門提供了

反射子產品,該子產品對Java原生的反射進行了良好的封裝,提供了更加簡潔易用的API, 友善上層使調用,并且對反射操作進行

了一系列優化,例如緩存了類的中繼資料,提高了反射操作的性能。

3.1.2 類型轉換子產品

對應type包

正如前面示例所示,MyBatis 為簡化配置檔案提供了别名機制,該機制是類型轉換子產品的主要功能之一。 類型轉換子產品的

另-一個功能是實作JDBC類型與Java類型之間的轉換,該功能在為SQL語句綁定實參以及映射查詢結果集時都會涉及。在為

SQL語句綁定實參時,會将資料由Java類型轉換成JDBC類型;而在映射結果集時,會将資料由JDBC類型轉換成Java類型。類

型轉換子產品的具體原理在第2章詳述。

3.1.3 日志子產品

對應logging包

無論在開發測試環境中,還是線上上生産環境中,日志在整個系統中的地位都是非常重要的。良好的日志功能可以幫助開發人

員和測試人員快速定位Bug代碼,也可以幫助運維人員快速定位性能瓶頸等問題。目前的Java世界中存在很多優秀的日志框

架,例如Log4j、Log4j2、 slf4j 等。MyBatis 作為-一個設計優良的架構,除了提供詳細的日志輸出資訊,還要能夠集

成多種日志架構,其日志子產品的一個主要功能就是內建第三方日志架構。

3.1.4 資源加載子產品

對應io包

資源加載子產品主要是對類加載器進行封裝,确定類加載器的使用順序,并提供了加載類檔案以及其他資源檔案的功能。

3.1.5 解析器子產品

對應parsing包

解析器子產品的主要提供了兩個功能:一個功能是對XPath進行封裝,為MyBatis初始化時解析mybatis- config.xml配置文

件以及映射配置檔案提供支援;另一個功能是為處理動态SQL語句中的占位符提供支援。

3.1.6 資料源子產品

對應datasource包

資料源是實際開發中常用的元件之一。 現在開源的資料源都提供了比較豐富的功能,例如,連接配接池功能、檢測連接配接狀态等,

選擇性能優秀的資料源元件對于提升ORM架構乃至整個應用的性能都是非常重要的。MyBatis 自身提供了相應的資料源實

現,當然MyBatis也提供了與第三方資料源內建的接口,這些功能都位于資料源子產品之中。

3.1.7 事務管理

對應transaction包

MyBatis對資料庫中的事務進行了抽象,其自身提供了相應的事務接口和簡單實作。在很多場景中,MyBatis 會與Spring

架構內建,并由Spring架構管理事務

3.1.8 緩存子產品

對應cache包

在優化系統性能時,優化資料庫性能是非常重要的一個環節,而添加緩存則是優化資料庫時最有效的手段之一。正确、合理地

使用緩存可以将一部分資料庫請求攔截在緩存這一層。MyBatis 中提供了一 級緩存和二級緩存,而這兩級緩存都是依賴于基

礎支援層中的緩存子產品實作的。這裡需要讀者注意的是,MyBatis中自帶的這兩級緩存與MyBatis 以及整個應用是運作在同

一個JVM中的,共享同一塊堆記憶體。如果這兩級緩存中的資料量較大,則可能影響系統中其他功能的運作,是以當需要緩存大

量資料時,優先考慮使用Redis、Memcache 等緩存産品。

3.1.9 Binding子產品

對應binding包

通過前面的示例我們知道,在調用SqlSession相應方法執行資料庫操作時,需要指定映射檔案中定義的SQL節點,如果出現

拼寫錯誤,我們隻能在運作時才能發現相應的異常。為了盡早發現這種錯誤,MyBatis 通過Binding子產品将使用者自定義的

Mapper接口與映射配置檔案關聯起來,系統可以通過調用自定義Mapper接口中的方法執行相應的SQL語句完成資料庫操作,

進而避免上述問題。值得讀者注意的是,開發人員無須編寫自定義Mapper接口的實作,MyBatis 會自動為其建立動态代理對

象。在有些場景中,自定義Mapper接口可以完全代替映射配置檔案,但有的映射規則和SQL語句的定義還是寫在映射配置檔案

中比較友善,例如動态SQL語句的定義。

3.1.10 注解子產品

對應annotation包

随着 Java 注解的慢慢流行,MyBatis 提供了注解的方式,使得我們友善的在 Mapper 接口上編寫簡單的資料庫 SQL 操作代碼,而無需像之前一樣,必須編寫 SQL 在 XML 格式的 Mapper 檔案中。雖然說,實際場景下,大家還是喜歡在 XML 格式的 Mapper 檔案中編寫響應的 SQL 操作。

3.1.11 異常子產品

對應 exceptions 包

定義了 MyBatis 專有的 PersistenceException 和 TooManyResultsException 異常,此外還包ExceptionFactory異常工廠。

3.2 核心處理層

3.2.1 配置解析

對應executor包

在MyBatis初始化過程中,會加載mybatis config.xml配置檔案、映射配置檔案以及Mapper接口中的注解資訊,解析後

的配置資訊會形成相應的對象并儲存到Configuration對象中。例如,示例中定義的節點(即ResultSet的映

射規則)會被解析成ResultMap對象;示例中定義的節點(即屬性映射)會被解析成ResultMapping對象。之後,利

用該Configuration對象建立SqlSessionFactory對象。待MyBatis 初始化之後,開發人員可以通過初始化得到

SqlSessionFactory 建立SqlSession對象并完成資料庫操作。

3.2.2 SQL解析與Scripting子產品

對應executor scripting包

拼湊SQL語句是一件煩瑣且易出錯的過程,為了将開發人員從這項枯燥無趣的工作中解脫出來,MyBatis實作動态SQL語句的

功能,提供了多種動态SQL語句對應的節點,例如,節點、 節點、 節點等。通過這些節點的組合

使用,開發人員可以寫出幾乎滿足所有需求的動态SQL語句。MyBatis中的scripting子產品會根據使用者傳入的實參,解析映射

檔案中定義的動态SQL節點,并形成資料庫可執行的SQL語句。之後會處理SQL語句中的占位符,綁定使用者傳入的實參。

3.2.3 SQL執行

SQL語句的執行涉及多個元件,其中比較重要的是Executor 、StatementHandler 、ParameterHandler和

ResultSetHandler. Executor 主要負責維護- - 級緩存和二級緩存,并提供事務管理的相關操作,它會将資料庫相關

操作委托給StatementHandler完成。StatementHandler首先通過ParameterHandler 完成SQL語句的實參綁定,然後

通過java. sql.Statement對象執行SQL語句并得到結果集,最後通過ResultSetHandler完成結果集的映射,得到結果

對象并傳回。

3.2.4 插件

對應plugin包

Mybatis 自身的功能雖然強大,但是并不能完美切合所有的應用場景,是以MyBatis提供了插件接口,我們可以通過添加用

戶自定義插件的方式對MyBatis進行擴充。使用者自定義插件也可以改變Mybatis的預設行為,例如,我們可以攔截SQL語句并

對其進行重寫。由于使用者自定義插件會影響MyBatis的核心行為,在使用自定義插件之前,開發人員需要了解MyBatis内部的

原理,這樣才能編寫出安全、高效的插件。

3.3 接口層

對應session包

接口層相對簡單,其核心是SqlSession 接口,該接口中定義了MyBatis 暴露給應用程式調用的API,也就是上層應用與

MyBatis互動的橋梁。接口層在接收到調用請求時,會調用核心處理層的相應子產品來完成具體的資料庫操作。

3.4 其他層

3.4.1 JDBC子產品

對應 jdbc 包

JDBC單元測試支援類。【隻能說是個測試挂件,白送都不要的那種,随便看看得了 】

3.4.2 Lang子產品

裡面隻包含兩個注解【從調用上好像沒有任何類用到這個。不知道幹啥用的!!原諒我的無知。】

3.5 小結

整體來說,MyBatis的代碼結構還是比較簡單易懂的。并且分包也比較清晰,見名知意。下面就是MyBatis的整體架構圖

原文位址

https://www.cnblogs.com/liuzhiyong0718/p/12463893.html