1. 程式人生 > >ibatis 核心原理解析

ibatis 核心原理解析

最近查詢一個生產問題的原因,需要深入研究 ibatis 框架的原始碼。雖然最後證明問題的原因與 ibatis 無關,但是這個過程加深了對 ibatis 框架原理的理解。

這篇文章主要就來講講 ibatis 框架的原理。

可能現在很多人已不再使用 ibatis 或者說也沒聽 ibatis,不過肯定了解過 Mybatis。ibatis 就是 Mybatis框架的前身,雖然 ibatis 框架已經比較老,但是其核心功能與 Mybatis 一致。

ibatis 解決的痛點

我們先看一個使用 JDBC 查詢的例子。

使用原生 JDBC 查詢,存在兩個痛點:

  1. 使用非常繁瑣,且需要處理各種資料庫異常,並且還需要關閉各種資源。
  2. 資料轉化麻煩。查詢之前需要從 Java 物件屬性值設定到 PreparedStatement中,查詢返回之後又需要從 ResultSet獲取返回設定到返回物件中。

在 ibatis 中封裝這些繁雜資料庫連線查詢程式碼,並處理了各類異常以及關閉各種資源。另外 ibatis 自動處理 Java 物件與資料庫型別之間的自動轉化,讓業務程式碼與 SQL 程式碼之間做到了解耦。

資料型別轉化原理

資料型別轉化主要分為兩類,一,傳入查詢的 Java 物件資料轉化成 SQL 型別資料。二 查詢返回的資料庫資訊對映到 Java 物件中。

ibatis SQL 需要定義在配置檔案中,一個查詢 SQL 語句配置如下:


      <select id="queryName" parameterClass="com.query.QueryDO"  resultClass="com.query.QueryDO" >
        select  * from  TEST_QUERY where ID=#id#

      </select>

ibatis 框架啟動過程將會解析配置檔案,生成 MappedStatement 的子類。如 select 配置會生成對應的 SelectStatement 物件。

MappedStatement

相關類圖如下。

MappedStatement 中將會儲存存在兩個重要的物件,ParameterMapResultMap,通過這兩個物件將會完成 Java 型別與資料庫型別的相互轉化。

Java 物件轉化成資料庫型別

以上面 select 配置為例,我們這裡需要做的是從傳入的 com.query.QueryDO物件中獲取屬性值,然後通過 PreparedStatement.setxx 設定到查詢引數中。

ibatis 解析配置中 SQL 語句時,將會獲取 # 之間的內容,將其替換成 ?。然後按照順序儲存到一個 ParameterMapping[] 陣列中,這個陣列將會儲存到 ParameterMap 物件中。

ParameterMapping 將會儲存解析欄位相關資訊。

最終解析後的 SQL 為:


select  * from  TEST_QUERY where ID=?

該 SQL 就可以通過 connection.prepareStatement("select * from TEST_QUERY where ID=?"); 生成 PreparedStatement 物件。

接著 ibatis 會根據 ParameterMappingparameterClass指定的型別建立合適的 dataExchangeparameterPlan物件。

其中 parameterPlan 物件會按照 ParameterMapping陣列中順序儲存了變數的 setter 和 getter 方法陣列。

dataExchange會按照 ParameterMapping 陣列中的順序使用反射獲取 parameterPlan getter 方法返回值生成 parameters 陣列。

最後迴圈 ParameterMapping 陣列,在 TypeHandler 呼叫 PreparedStatement.setxx 設定相關值。

TypeHandler 存在很多子類,通過這些子類正確處理了 Java 物件與資料庫型別轉化。

轉化的時序圖為:

時序圖來源於:https://www.ibm.com/developerworks/cn/java/j-lo-ibatis-principle/index.html

資料庫欄位對映到 Java 物件

SQL 執行結束之後將會返回查詢結果,這裡將會使 SQL 查詢結果轉化為返回結果 com.query.QueryDO。這裡需要用到上面提到 ResultMap 物件。

當 SQL 執行結束返回 ResultSet 物件之後,使用 ResultSet.getMetaData() 獲取返回資訊元資料物件 ResultSetMetaData

ResultSetMetaData 可以獲取返回結果欄位名,型別等資訊,然後按照順序存入 ResultMapping 陣列中。

然後按照 ResultMapping 陣列中使用 TypeHandler呼叫 ResultSet.getxx 獲取實際返回資料,儲存到 columnValues 陣列中。

ResultMap 物件會根據 ResultMappingresultClass指定的型別合適的 dataExchangeresultPlan物件。resultPlan物件與上面的 parameterPlan物件一樣也會儲存著變數的 setter 和 getter 方法陣列。

最後先根據 resultClass 反射生成返回物件,然後使用反射呼叫 resultPlan setter 方法,依次設定相關值。

對映返回物件時序圖為:

時序圖來源於:https://www.ibm.com/developerworks/cn/java/j-lo-ibatis-principle/index.html

ibatis 樣板程式碼

上面講完了 ibatis 資料型別的轉化原理,接著我們來看下 ibatis 呼叫 JDBC 樣板程式碼。

使用 ibatis 執行查詢語句時,如 queryForObject,呼叫到 SqlMapExecutorDelegate 。在 SqlMapExecutorDelegate 中將會會做一些前提準備,比如準備事務,最後會將 SQL 語句委託給 SqlExecutor 執行。

這裡使用委託者模式,接受請求的物件將請求委託給另一個物件來處理。這種模式的優點在於解耦了業務程式碼與實際執行程式碼的聯絡,在於對外隱藏真正執行物件,易於擴充套件。

SqlExecutor#executeQuery 執行過程主要分為以下三步。

第一步,獲取 PreparedStatement,使用 conn.prepareStatement(sql) 獲取。

第二步呼叫 PreparedStatement.setxxx 方法設定引數。上文中的 Java 物件型別轉化成 SQL 型別在這裡完成。

第三步,呼叫 PreparedStatement.execute() 執行 SQL 語句。

第四步,使用 ResultSet 獲取返回值,在這一步將會完成 資料庫型別與 Java 型別的轉化。

幫助連結

深入分析 iBATIS 框架之系統架構與對映原理

相關推薦

ibatis 核心原理解析

最近查詢一個生產問題的原因,需要深入研究 ibatis 框架的原始碼。雖然最後證明問題的原因與 ibatis 無關,但是這個過程加深了對 ibatis 框架原理的理解。 這篇文章主要就來講講 ibatis 框架的原理。 可能現在很多人已不再使用 ibatis 或者說也沒聽 ibatis,不過肯定了解過 My

[轉]GeoHash核心原理解析

解析 知識 比較 lpad 文章 target .org 情況 作者 註:最近做項目需要這方面的知識,恰逢此文,甚喜。我轉的文章也是轉別人的,未找到原作者。 引子 機機是個好動又好學的孩子,平日裏就喜歡拿著手機地圖點點按按來查詢一些好玩的東西。某一天機機到北海公園

GeoHash核心原理解析

引子   機機是個好動又好學的孩子,平日裡就喜歡拿著手機地圖點點按按來查詢一些好玩的東西。某一天機機到北海公園遊玩,肚肚餓了,於是乎開啟手機地圖,搜尋北海公園附近的餐館,並選了其中一家用餐。     飯飽之後機機開始反思了,地圖後臺如何根據自己所在位置查詢來查詢附近餐館的呢?苦思冥想了半天,機機想出

Java併發包JUC核心原理解析

> CS-LogN思維導圖:記錄CS基礎 面試題 開源地址:https://github.com/FISHers6/CS-LogN ![](https://img2020.cnblogs.com/blog/1454456/202006/1454456-20200625122837407-1152312809

Mybatis(四):MyBatis核心元件介紹原理解析和原始碼解讀 java中代理,靜態代理,動態代理以及spring aop代理方式,實現原理統一彙總

Mybatis核心成員 Configuration        MyBatis所有的配置資訊都儲存在Configuration物件之中,配置檔案中的大部分配置都會儲存到該類中 SqlSession         &

Netty進階:Netty核心NioEventLoop原理解析

Netty提供了Java NIO Reactor模型的實現,之前寫過一篇文章是對三種Reactor模式的簡單實現:Reactor模型的Java NIO實現,當然netty中的實現要複雜的多。並且Netty將實現好的Reactor模型封裝起來,我們只需提供適當的

Struts2核心工作原理解析

這是Struts2官方站點提供的Struts 2 的整體結構。 一個請求在Struts2框架中的處理大概分為以下幾個步驟: 客戶端提起一個(HttpServletRequest)請求,如上文在瀏覽器中輸入”http://localhost:8080/TestMv

Dubbo原理解析-Dubbo核心實現之基於SPI思想Dubbo核心實現(轉)

SPI介面定義 定義了@SPI註解 public @interface SPI {   String value() default ""; //指定預設的擴充套件點 } 只有在介面打了@SPI註解的介面類才會去查詢擴充套件點實現 會依次從這幾個檔案中讀取擴

java多執行緒程式設計的核心——AQS原理解析

AQS是什麼 java concurrent包中有很多阻塞類如:ReentrantLock、ReentrantReadWriteLock、CountDownLatch、Semaphore、Synchronous、FutureTask等,他們的底層都是根據aqs構

Kafka原始碼深度解析-序列4 -Producer -network層核心原理

在上一篇我們分析了Java NIO的原理和使用方式,本篇將進一步分析Kafka client是如何基於NIO構建自己的network層。 network層的分層架構 下圖展示了從最上層的KafkaProducer到最底層的Java NIO的構建層次關係:

深入解析Koa之核心原理

esp 隊列 null 很多 respond 結合 patch ... targe 這篇文章主要介紹了玩轉Koa之核心原理分析,本文從封裝創建應用程序函數、擴展res和req、中間件實現原理、異常處理的等這幾個方面來介紹,寫的十分的全面細致,具有一定的參考價值,對此有需要的

2. Dubbo原理解析-Dubbo核心實現之基於SPI思想Dubbo核心實現

SPI介面定義 定義了@SPI註解 public @interface SPI {        Stringvalue() default ""; //指定預設的擴充套件點 }  只有在介面打了@SPI註解的介面類才會去查詢擴充套件點實現 會依次從這幾個檔案中讀取擴充套

SpringBoot 原始碼解析 (一)----- SpringBoot核心原理入門

Spring Boot 概述 Build Anything with Spring Boot:Spring Boot is the starting point for building all Spring-based applications. Spring Boot is designed to ge

《大型網站技術架構:核心原理與案例分析》-- 讀書筆記 (5) :網購秒殺系統

案例 並發 刷新 隨機 url 對策 -- 技術 動態生成 1. 秒殺活動的技術挑戰及應對策略 1.1 對現有網站業務造成沖擊 秒殺活動具有時間短,並發訪問量大的特點,必然會對現有業務造成沖擊。對策:秒殺系統獨立部署 1.2 高並發下的應用、

[Architect] Abp 框架原理解析(5) UnitOfWork

框架 方法 src options nalu res actions cnblogs 一個數 本節目錄 介紹 分析Abp源碼 實現UOW 介紹 UOW(全稱UnitOfWork)是指工作單元. 在Abp中,工作單元對於倉儲和應用服務方法默認開啟。並在一次請求中,共享

angularjs工作原理解析

body oot 分隔 復制 抖動 修改 重新 接收 裏的 個人覺得,要很好的理解AngularJS的運行機制,才能盡可能避免掉到坑裏面去。在這篇文章中,我將根據網上的資料和自己的理解對AngularJS的在啟動後,每一步都做了些什麽,做一個比較清楚詳細的解析。 首

USB Type-C工作原理解析

說明 是否 forms dfp 其他 耗時 def 左右 del 自從蘋果發布了新MacBook,USB Type-C接口就成為了熱議對象。我來從硬件角度解析下這個USB Type-C,以便大家更好的了解USB Type-C的工作原理。特色尺寸小,支持正反插,速度快(10G

LocationManager(一)-定位方式原理解析

一段時間 接入點 work use npr roi 無線網 服務器 輔助 參考資源:android 4種定位原理及實現——1 android使用不同的方法為應用提供位置信息。 定位的方式有三種:GPS地位(A-GPSAssistedGPS:輔助全球衛星定位系統,或者是同步G

移動端使用rem同時適應安卓ios手機原理解析,移動端響應式開發

size screen bsp 應用 屏幕 來看 比例 忽略 基礎 rem單位大家可能已經很熟悉,rem是隨著html的字體大小來顯示代表寬度的方法,我們怎樣進行移動端響應式開發呢 瀏覽器默認的字體大小為16px 及1rem 等於 16px 如果我們想要使1rem等於 12

Android核心服務解析篇(三)——Android系統的啟動

onf med cin gets get lld 系統屬性 基本 安裝模塊 從大的方面來說。Android系統的啟動能夠分為兩個部分:第一部分是Linux核心的啟動,第二部分是Android系統的啟動。第一部分主要包含系統引導,核心和驅動程序等,因為它們不屬於本篇要講的