深入詳解Mybatis的架構原理與6大核心流程

深入詳解Mybatis的架構原理與6大核心流程-mikechen的互聯網架構

MyBatis 是 Java 生態中非常著名的一款 ORM 框架,目前在一線互聯網大廠中應用廣泛,Mybatis已經成為了一個必會框架。

如果你想要進入一線大廠,能夠熟練使用 MyBatis 開發已經是一項非常基本的技能,同時大廠也更希望自己的開發人員深入了解 MyBatis 框架的原理和核心實現。

從這個角度看,理解 MyBatis 原理,閱讀 MyBatis核心源碼,這樣更有利於提高職場競爭力。

在深入了解Mybatis的源碼之前,我們先了解一下Mybatis的整體架構和工作原理,這樣有助於我們在閱讀源碼過程中了解思路和流程。

Mybatis架構設計

我們把Mybatis的功能架構分為三層:

  1. API介面層
  2. 數據處理層
  3. 基礎支撐層

深入詳解Mybatis的架構原理與6大核心流程-mikechen的互聯網架構

介面層

介面層:主要就是和資料庫交互,提供給外部使用的介面API,開發人員通過這些本地API來操縱資料庫,介面層一接收到調用請求就會調用數據處理層來完成具體的數據處理。

深入詳解Mybatis的架構原理與6大核心流程-mikechen的互聯網架構

以使用Mapper介面為例,將配置文件中的每一個 節點抽象為一個 Mapper 介面,這個介面中聲明的方法和跟Mapper.xml中的 節點項對應。

id值對應方法名稱,parameterType 值對應方法的入參類型,而resultMap 值則對應返回值類型。

深入詳解Mybatis的架構原理與6大核心流程-mikechen的互聯網架構

配置好後,MyBatis 會根據介面聲明的方法資訊,通過動態代理機制生成一個Mapper 實例,當調用介面方法時,根據這個方法的方法名和參數類型,確定Statement Id,底層還是通過 SqlSession.select/update( 「statementId」, parameter) 等來實現對資料庫的操作。

數據處理層

數據處理層:可以說是MyBatis 的核心,負責具體的SQL查找、SQL解析、SQL執行和執行結果映射處理等,它主要的目的是根據調用的請求完成一次資料庫操作。

深入詳解Mybatis的架構原理與6大核心流程-mikechen的互聯網架構

從大的方面上講,它要完成兩個功能:

  • 通過傳入參數構建動態SQL語句
  • SQL語句的執行以及封裝查詢結果集

1.通過傳入參數構建動態SQL語句

動態語句生成能夠說是MyBatis框架很是優雅的一個設計,MyBatis 經過傳入的參數值,使用 Ognl 來動態地構造SQL語句,使得MyBatis 有很強的靈活性和擴展性。

參數映射指的是對於java 數據類型和jdbc數據類型之間的轉換,這裡有包括兩個過程:

  • 查詢階段
  • 查詢結果集轉換階段

查詢階段要將java類型的數據,轉換成jdbc類型的數據,經過 preparedStatement.setXXX() 來設值;

另外一個就是對resultset查詢結果集的jdbcType 數據轉換成java 數據類型。

2. SQL語句的執行以及封裝查詢結果集

動態SQL語句生成以後,MyBatis 將執行SQL語句,並將可能返回的結果集轉換成List<E> 列表。

MyBatis 在對結果集的處理中,支援結果集關係一對多和多對一的轉換,而且有兩種支援方式,一種為嵌套查詢語句的查詢,還有一種是嵌套結果集的查詢。

基礎支撐層

基礎支撐層是整個MyBatis框架的地基,負責最基礎的功能支撐,包括連接管理、事務管理、配置載入和快取處理,這些都是共用的東西,將他們抽取出來作為最基礎的組件,為上層的數據處理層提供最基礎的支撐。

深入詳解Mybatis的架構原理與6大核心流程-mikechen的互聯網架構

1.快取機制

資料庫是實踐生成中非常核心的存儲,很多業務數據都會落地到資料庫,所以資料庫性能的優劣直接影響了上層業務系統的優劣。

我們很多線上業務都是讀多寫少的場景,在資料庫遇到瓶頸時,快取是最有效、最常用的手段之一,正確使用快取可以將一部分資料庫請求攔截在快取這一層,這就能夠減少一部分資料庫的壓力,提高系統性能。

深入詳解Mybatis的架構原理與6大核心流程-mikechen的互聯網架構

除了使用 Redis、Memcached 等外置的第三方快取以外,持久化框架一般也會自帶內置的快取,例如,MyBatis 就提供了一級快取和二級快取,具體實現位於基礎支撐層的快取模組中。

2.反射工具

該模組對 Java 原生的反射進行了良好的封裝,提供了更加簡潔易用的 API ,方便上層使調用,並且對反射操作進行了一系列優化,例如快取了類的元數據,提高了反射操作的性能。

3.類型轉換

類型轉換模組提供了兩個主要功能,一個功能是別名機制,MyBatis 為了簡化配置文件提供了別名機制。

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

4.日誌

提供詳細的日誌輸出資訊,並且能夠集成多種日誌框架,其日誌模組的一個主要功能就是集成第三方日誌框架。

5.資源載入

資源載入模組主要是對類載入器進行封裝,確定類載入器的使用順序,並提供了載入類文件以及其他資源文件的功能。

6.解析器

解析器模組主要提供兩個功能,一個功能是對 XPath 進行封裝,為 MyBatis 初始化時解析 mybatis-config.xml 配置文件以及映射配置文件提供支援。

另一個功能是為處理動態 SQL 語句中的佔位符提供支援。

7.事務管理

持久層框架一般都會提供一套事務管理機制實現資料庫的事務控制,MyBatis 對資料庫中的事務進行了一層簡單的抽象,提供了簡單易用的事務介面和實現。

一般情況下,Java 項目都會集成 Spring,並由 Spring 框架管理事務。

8.Binding

在調用 SqlSession 相應方法執行資料庫操作時,需要指定映射文件中定義的 SQL 節點,如果出現拼寫錯誤,我們只能在運行時才能發現相應的異常。為了儘早發現這種錯誤,MyBatis 通過 Binding 模組將用戶自定義的 Mapper 介面與映射配置文件關聯起來,系統可以通過調用自定義 Mapper 介面中的方法執行相應的SQL 語句完成資料庫操作,從而避免上述問題。

需要注意的是,開發人員無須編寫自定義 Mapper 介面的實現,MyBatis 會自動為其創建動態代理對象。

9.數據源

對於 ORM 框架而言,數據源的組織是一個非常重要的一部分,這直接影響到框架的性能問題。

資料庫連接是一項有限的昂貴資源,一個資料庫連接對象均對應一個物理資料庫連接,每次操作都打開一個物理連接,使用完都關閉連接,這樣造成系統的性能低下。

資料庫連接池的解決方案是在應用程式啟動時建立足夠的資料庫連接,並將這些連接組成一個連接池,由應用程式動態地對池中的連接進行申請、使用和釋放。

打開Mybatis源碼找到datasource包下就可以看到連接池的實現,如下圖所示:

深入詳解Mybatis的架構原理與6大核心流程-mikechen的互聯網架構

Mybatis核心執行流程

mybatis的總體執行流程,總結如下:

深入詳解Mybatis的架構原理與6大核心流程-mikechen的互聯網架構

1.MyBatis配置文件

config.xml:配置了全局配置文件,配置了MyBatis的運行環境等資訊。

mapper,xml:sql的映射文件,配置了操作資料庫的sql語句,此文件需在config.xml中載入。

2.SqlSessionFactory

通過MyBatis環境等配置資訊構造SqlSessionFactory(會話工廠)。

3.SqlSession

通過會話工廠創建SqlSession(會話),對資料庫進行增刪改查操作。

4.Exector執行器

MyBatis底層自定義了Exector執行器介面來具體操作資料庫,Exector介面有兩個實現,一個基本執行器(默認),一個是快取執行器,SqlSession底層是通過Exector介面操作資料庫。

5.MappedStatement

MyBatis的一個底層封裝對象,它包裝了MyBatis配置資訊與sql映射資訊等。mapper.xml中的insert/select/update/delete標籤對應一個MappedStatement對象。標籤的id就是MappedStatement的id。

MappedStatement對sql執行輸入參數進行定義,包括HashMap、基本類型、pojo、Executor通過MappedStatement在執行sql前將輸入的Java對象映射至sql中,輸入參數映射就是JDBC編程對preparedStatement設置參數。

MappedStatement對sql執行輸出結果進行定義,包括HashMap、基本類型、pojo,Executor通過MappedStatement在執行sql後將輸出結果映射至Java對象中,輸出結果映射就是JDBC編程對結果的解析處理過程。

​到此我就把Mybatis的架構從全局上做了一個拆解,後續我將重點分析其核心源碼,這樣先全局再局部,這樣更有利於掌握其核心原理實現,希望這個框架系列能對你有所用。


 

關於作者:mikechen,十餘年BAT架構經驗,資深技術專家,曾任職阿里、淘寶、百度。

歡迎關注個人公眾號:mikechen的互聯網架構,十餘年BAT架構經驗傾囊相授!

在公眾號菜單欄對話框回復【架構】關鍵詞,即可查看我原創的300期+BAT架構技術系列文章與1000+大廠面試題答案合集。