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

mikechen的網際網路架構發表於2022-08-12

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

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

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

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

Mybatis 架構設計

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

  1. API 介面層
  2. 資料處理層
  3. 基礎支撐層

介面層

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

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

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

配置好後,MyBatis 會根據介面宣告的方法資訊,透過 動態代理機制生成一個 Mapper 例項,當呼叫介面方法時,根據這個方法的方法名和引數型別,確定 Statement Id,底層還是透過 SqlSession.select/update (“statementId”, parameter) 等來實現對資料庫的操作。

資料處理層

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

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

  • 透過傳入引數構建動態 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 框架的地基,負責最基礎的功能支撐,包括連線管理、事務管理、配置載入和快取處理,這些都是共用的東西,將他們抽取出來作為最基礎的元件,為上層的資料處理層提供最基礎的支撐。

1. 快取機制

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

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

除了使用 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 核心執行流程

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

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,10年+大廠架構經驗,《BAT架構技術500期》系列文章作者,分享十餘年BAT架構經驗以及面試心得!


閱讀mikechen的網際網路架構更多技術文章合集

| | | | | | | 架構師


關注「mikechen 的網際網路架構」公眾號,回覆 【架構】領取我原創的《300 期 + BAT 架構技術系列與 1000 + 大廠面試題答案》


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70011997/viewspace-2910118/,如需轉載,請註明出處,否則將追究法律責任。

相關文章