MyBatis深刻(2)-項目結構

概述

本文的目的是讓讀者能對 MyBatis 的項目結構有一個簡單的瞭解。java

另外,在 http://www.mybatis.org 中提供了很不錯的 MyBatis 中文文檔,若是遇到一些問題能夠翻閱一波。sql

總體架構

拉取完 MyBatis 項目後,咱們會發現該項目分爲不少包,以下:數據庫

 其實 MyBatis 的總體架構分爲三層:緩存

  1. 基礎支持層
  2. 核心處理層
  3. 接口層

基礎支持層

基礎支持層,包含整個 MyBatis 的基礎模塊,這些模塊爲核心處理層的功能提供了良好的支撐。安全

反射模塊

對應 reflection 包。session

Java 中的反射雖然功能強大,但對大多數開發人員來講,寫出高質量的反射代碼仍是 有必定難度的。MyBatis 中專門提供了反射模塊,該模塊對 Java 原生的反射進行了良好的封裝,提了更加簡潔易用的 API,方便上層使調用,而且對反射操做進行了一系列優化,例如緩存了類的元數據,提升了反射操做的性能。mybatis

類型轉換模塊

對應 type 包。架構

一、 MyBatis 爲簡化配置文件提供了別名機制,該機制是類型轉換模塊的主要功能之一。app

二、類型轉換模塊的另外一個功能是實現 JDBC 類型與 Java 類型之間的轉換,該功能在爲 SQL 語句綁定實參以及映射查詢結果集時都會涉及:框架

  • 在爲 SQL 語句綁定實參時,會將數據由 Java 類型轉換成 JDBC 類型。
  • 而在映射結果集時,會將數據由 JDBC 類型轉換成 Java 類型。

日誌模塊

對應 logging 包。

不管在開發測試環境中,仍是在線上生產環境中,日誌在整個系統中的地位都是很是重要的。良好的日誌功能能夠幫助開發人員和測試人員快速定位 Bug 代碼,也能夠幫助運維人員快速定位性能瓶頸等問題。目前的 Java 世界中存在不少優秀的日誌框架,例如 Log4j、 Log4j二、Slf4j 等。 MyBatis 做爲一個設計優良的框架,除了提供詳細的日誌輸出信息,還要可以集成多種日誌框架,其日誌模塊的一個主要功能就是集成第三方日誌框架。

IO模塊

對應 io 包。

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

解析器模塊

對應 parsing 包。

解析器模塊,主要提供了兩個功能:

  • 一個功能,是對 XPath 進行封裝,爲 MyBatis 初始化時解析 mybatis-config.xml 配置文件以及映射配置文件提供支持。
  • 另外一個功能,是爲處理動態 SQL 語句中的佔位符提供支持。

數據源模塊

對應 datasource 包。

數據源是實際開發中經常使用的組件之一。如今開源的數據源都提供了比較豐富的功能,例如,鏈接池功能、檢測鏈接狀態等,選擇性能優秀的數據源組件對於提高 ORM 框架乃至整個應用的性能都是很是重要的。

MyBatis 自身提供了相應的數據源實現,固然 MyBatis 也提供了與第三方數據源集成的接口,這些功能都位於數據源模塊之中。

事務管理模塊

對應 transaction 包。

MyBatis 對數據庫中的事務進行了抽象,其自身提供了相應的事務接口和簡單實現。

在不少場景中,MyBatis 會與 Spring 框架集成,並由 Spring 框架管理事務。

緩存模塊

對應 cache 包。

在優化系統性能時,優化數據庫性能是很是重要的一個環節,而添加緩存則是優化數據庫時最有效的手段之一。正確、合理地使用緩存能夠將一部分數據庫請求攔截在緩存這一層。 MyBatis 中提供了一級緩存和二級緩存,而這兩級緩存都是依賴於基礎支持層中的緩 存模塊實現的。這裏須要讀者注意的是,MyBatis 中自帶的這兩級緩存與 MyBatis 以及整個應用是運行在同一個 JVM 中的,共享同一塊堆內存。若是這兩級緩存中的數據量較大, 則可能影響系統中其餘功能的運行,因此當須要緩存大量數據時,優先考慮使用 Redis、Memcache 等緩存產品。

綁定模塊

對應 binding 包。

在調用 SqlSession 相應方法執行數據庫操做時,須要指定映射文件中定義的 SQL 節點,若是出現拼寫錯誤,咱們只能在運行時才能發現相應的異常。爲了儘早發現這種錯誤,MyBatis 經過 Binding 模塊,將用戶自定義的 Mapper 接口與映射配置文件關聯起來,系統能夠經過調用自定義 Mapper 接口中的方法執行相應的 SQL 語句完成數據庫操做,從而避免上述問題。

值得讀者注意的是,開發人員無須編寫自定義 Mapper 接口的實現,MyBatis 會自動爲其建立動態代理對象。在有些場景中,自定義 Mapper 接口能夠徹底代替映射配置文件,但有的映射規則和 SQL 語句的定義仍是寫在映射配置文件中比較方便,例如動態 SQL 語句的定義。

註解模塊

對應 annotations 包。

隨着 Java 註解的慢慢流行,MyBatis 提供了註解的方式,使得咱們方便的在 Mapper 接口上編寫簡單的數據庫 SQL 操做代碼,而無需像以前同樣,必須編寫 SQL 在 XML 格式的 Mapper 文件中。實際場景下,你們仍是喜歡在 XML 格式的 Mapper 文件中編寫響應的 SQL 操做。

異常模塊

對應 exceptions 包。

定義了 MyBatis 專有的 PersistenceException 和 TooManyResultsException 異常。

核心處理層

在覈心處理層中,實現了 MyBatis 的核心處理流程,其中包括 MyBatis 的初始化以及完成一次數據庫操做的涉及的所有流程 。 

配置解析

對應 builder 和 mapping 模塊。前者爲解析配置過程,後者主要爲解析 SQL 操做中的映射關係。

在 MyBatis 初始化過程當中,會加載 mybatis-config.xml 配置文件、映射配置文件以及 Mapper 接口中的註解信息,解析後的配置信息會造成相應的對象並保存到 Configuration 對象中。例如:

  • <resultMap> 節點(即 ResultSet 的映射規則) 會被解析成 ResultMap 對象。
  • <result> 節點(即屬性映射)會被解析成 ResultMapping 對象。

以後,利用該 Configuration 對象建立 SqlSessionFactory 對象。待 MyBatis 初始化以後,開發人員能夠經過初始化獲得 SqlSessionFactory 建立 SqlSession 對象並完成數據庫操做。

SQL解析

對應 scripting 模塊。

拼湊 SQL 語句是一件煩瑣且易出錯的過程,爲了將開發人員從這項枯燥無趣的工做中 解脫出來,MyBatis 實現動態 SQL 語句的功能,提供了多種動態 SQL語句對應的節點。例如 <where> 節點、 <if> 節點、 <foreach> 節點等 。經過這些節點的組合使用, 開發人 員能夠寫出幾乎知足全部需求的動態 SQL 語句。

MyBatis 中的 scripting 模塊,會根據用戶傳入的實參,解析映射文件中定義的動態 SQL 節點,並造成數據庫可執行的 SQL 語句。以後會處理 SQL 語句中的佔位符,綁定用戶傳入的實參。

SQL執行

對應 executor 和 cursor 模塊。前者對應執行器,後者對應執行結果的遊標。

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

  • Executor 主要負責維護一級緩存和二級緩存,並提供事務管理的相關操做,它會將數據庫相關操做委託給 StatementHandler 完成。
  • StatementHandler 首先經過 ParameterHandler 完成 SQL 語句的實參綁定,而後經過 java.sql.Statement 對象執行 SQL 語句並獲得結果集,最後經過 ResultSetHandler 完成結果集的映射,獲得結果對象並返回。

總體過程以下圖:

插件

對應 plugin 模塊。

Mybatis 自身的功能雖然強大,可是並不能完美切合全部的應用場景,所以 MyBatis 提供了插件接口,咱們能夠經過添加用戶自定義插件的方式對 MyBatis 進行擴展。用戶自定義插件也能夠改變 Mybatis 的默認行爲,例如,咱們能夠攔截 SQL 語句並對其進行重寫。

因爲用戶自定義插件會影響 MyBatis 的核心行爲,在使用自定義插件以前,開發人員須要瞭解 MyBatis 內部的原理,這樣才能編寫出安全、高效的插件。

接口層

對應 session 模塊。

接口層相對簡單,其核心是 SqlSession 接口,該接口中定義了 MyBatis 暴露給應用程序調用的 API,也就是上層應用與 MyBatis 交互的橋樑。接口層在接收到調用請求時,會調用核心處理層的相應模塊來完成具體的數據庫操做。

相關文章
相關標籤/搜索