溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Mybatis最硬核的API是什么

發(fā)布時(shí)間:2021-10-20 15:40:30 來源:億速云 閱讀:157 作者:iii 欄目:編程語言

本篇內(nèi)容主要講解“Mybatis最硬核的API是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Mybatis最硬核的API是什么”吧!

1、Mybatis 架構(gòu)與核心API

不出意外的話,在后續(xù)源碼剖析相關(guān)文章中,我們會對 Mybatis 的源碼進(jìn)行一次大掃蕩,一起挖掘每一處值得大家深入理解/記憶的知識點(diǎn)。而在本文中,我們主要先把 Mybatis 的架構(gòu)/層次鋪開,俯視 Mybatis 架構(gòu)的設(shè)計(jì)全貌,再把幾個(gè)硬核的 API 詳細(xì)消化。

整體順序脈絡(luò),希望讓你有所期待 ~

Mybatis最硬核的API是什么

我們先簡單揭開 Mybatis 神秘的源碼包,

瞅瞅 Ta 大致目錄結(jié)構(gòu) :

Mybatis最硬核的API是什么

看,Mybatis 的源代碼包整齊劃一排在 org.apache.ibatis 目錄下,基本設(shè)計(jì)用途我簡單梳理成上面這張圖,方便大家直觀理解,當(dāng)然只看源碼包目錄結(jié)構(gòu),難免會顯得枯燥無物,所以我們再看一下,其實(shí) Mybatis 的源碼包功能上可以是這么劃分:

Mybatis最硬核的API是什么

上圖讓我們對 Mybatis 的架構(gòu)有了抽象的理解。

然而,實(shí)際上具體的職能分工,核心 API 的場景應(yīng)用,到底會是怎樣一套流程呈現(xiàn)呢?

看下面這幅功能架構(gòu)設(shè)計(jì),或許你能更好的理解。

Mybatis最硬核的API是什么

根據(jù) Mybatis 功能架構(gòu)我們劃分成三層

  • 接口層:該層提供一系列接口讓用戶直接參與使用,包含信息配置與實(shí)際數(shù)據(jù)操作調(diào)用。配置方式包括:基于 XML 配置方式、基于 Java API 配置方式兩種方式,用戶也可以通過接口層 API 對數(shù)據(jù)庫發(fā)起增刪改查等操作的請求, 本層接口會把接收到的調(diào)用請求交給數(shù)據(jù)處理層的構(gòu)件去處理。

  • 數(shù)據(jù)處理層:該層是 Mybatis 的核心層,負(fù)責(zé)數(shù)據(jù)處理,主要包括SQL 參數(shù)映射解析、SQL 語句的實(shí)際執(zhí)行、執(zhí)行結(jié)果集的映射處理等。

  • 框架支撐層:該層屬于 Mybatis 的后勤保障層,包括數(shù)據(jù)庫連接管理、事務(wù)把控管理、配置加載與緩存處理、日志處理、異常處理等,提供基礎(chǔ)支撐能力,保障上層的數(shù)據(jù)處理。

我們知道,Mybatis 框架讓用戶只需要提供配置信息,并且專注于 SQL 的編寫即可,對于連接管理數(shù)據(jù)庫/事務(wù),或?qū)嶋H的 SQL 參數(shù)映射/語句執(zhí)行/結(jié)果集映射等操作,作為用戶都并不需要操心和參與。

但是,好奇的我們其實(shí)想知道,Mybatis 核心部分的數(shù)據(jù)處理在整體流程中,是如何支撐用戶請求?同時(shí)各個(gè)構(gòu)件之間交互,又是怎樣流轉(zhuǎn)呢?

很巧,我這里有一張圖,介紹了整體流程:

Mybatis最硬核的API是什么

根據(jù)以上框架流程圖進(jìn)行講解

  • 創(chuàng)建配置并調(diào)用API:這一環(huán)節(jié)發(fā)生在應(yīng)用程序端,是開發(fā)人員在實(shí)際應(yīng)用程序中進(jìn)行的兩步操作,第一步創(chuàng)建核心配置文件 Configuration.xml 和映射文件 mapper.xml (通過注解方式也可創(chuàng)建以上兩種配置),準(zhǔn)備好基礎(chǔ)配置和 SQL 語句之后;第二步就是直接調(diào)用 Mybatis 框架中的數(shù)據(jù)庫操作接口。

  • 加載配置并初始化:Mybatis 框架會根據(jù)應(yīng)用程序端提供的核心配置文件與 SQL 映射文件的內(nèi)容,使用資源輔助類 Resources 把配置文件讀取成輸入流,然后通過對應(yīng)的解析器解析并封裝到 Configuration 對象和 MappedStatement 對象,最終把對象存儲在內(nèi)存之中。

  • 創(chuàng)建會話并接收請求:在 Mybatis 框架加載配置并初始化配置對象之后,會話工廠構(gòu)建器 SqlSessionFactoryBuilder 同時(shí)創(chuàng)建會話工廠 SqlSessionFactory,會話工廠會根據(jù)應(yīng)用程序端的請求,創(chuàng)建會話 SqlSession,以便應(yīng)用程序端進(jìn)行數(shù)據(jù)庫交互。

  • 處理請求:SqlSession 接收到請求之后,實(shí)際上并沒有進(jìn)行處理,而是把請求轉(zhuǎn)發(fā)給執(zhí)行器 Executor,執(zhí)行器再分派到語句處理器 StatementHandler ,語句處理器會結(jié)合參數(shù)處理器 ParameterHandler ,進(jìn)行數(shù)據(jù)庫操作(底層封裝了 JDBC Statement 操作)。

  • 返回處理結(jié)果:每個(gè)語句處理器 StatementHandler 處理完成數(shù)據(jù)庫操作之后,會協(xié)同 ResultSetHandler 以及類型處理器 TypeHandler ,對底層 JDBC 返回的結(jié)果集進(jìn)行映射封裝,最終返回封裝對象。

針對以上總體框架流程涉及到的這些硬核 API,下面我們逐個(gè)展開介紹,但不會詳細(xì)剖析源碼與原理,包括構(gòu)建細(xì)節(jié),因?yàn)檫@些我們在后續(xù)的源碼剖析章節(jié)中都會詳細(xì)分析。

Mybatis最硬核的API是什么

2、Configuration – 全局配置對象

對于 Mybatis 的全局配置對象 Configuration,我相信無論是初學(xué)者還是資深玩家,都不會陌生。整個(gè) Mybatis 的宇宙,都圍繞著 Configuration 轉(zhuǎn)。Configuration 對象的結(jié)構(gòu)和 config.xml 配置文件的內(nèi)容幾乎相同,涵蓋了properties (屬性),settings (設(shè)置),typeAliases (類型別名),typeHandlers (類型處理器),objectFactory (對象工廠),mappers (映射器)等等,之前我們有專門的一篇文章詳細(xì)進(jìn)行介紹,感興趣的朋友往上翻到目錄列表,找到 《Mybatis系列全解(四):全網(wǎng)最全!Mybatis配置文件XML全貌詳解》 一文詳細(xì)品味一番吧。

Mybatis最硬核的API是什么

配置對象 Configuration 通過解析器 XMLConfigBuilder 進(jìn)行解析,把全局配置文件 Config.xml 與 映射器配置文件 Mapper.xml 中的配置信息全部構(gòu)建成完整的 Configuration 對象,后續(xù)我們源碼分析時(shí)詳細(xì)剖析整個(gè)過程。

Mybatis最硬核的API是什么

3、Resources – 資源輔助類

我們知道,像 Configuration 和 Mapper 的配置信息存放在 XML 文件中,Mybatis 框架在構(gòu)建配置對象時(shí),必須先把 XML 文件信息加載成流,再做后續(xù)的解析封裝,而 Resources 作為資源的輔助類,恰恰干的就是這個(gè)活,無論是通過加載本地資源或是加載遠(yuǎn)程資源,最終都會通過 類加載器 訪問資源文件并輸出文件流。

Mybatis最硬核的API是什么

//加載核心配置文件
InputStream resourceAsStream = 
    Resources.getResourceAsStream("Config.xml");

Resources 實(shí)實(shí)在在提供了一系列方法分分鐘解決你的文件讀取加載問題:

Mybatis最硬核的API是什么

Mybatis最硬核的API是什么

4、SqlSessionFactoryBuilder – 會話工廠構(gòu)建器

我們一撞見 xxxBuilder ,就大致能知道它是某類對象的構(gòu)建器,這里 SqlSessionFactoryBuilder 也是一樣,它是 Mybatis 中的一個(gè)會話工廠構(gòu)建器,在資源輔助類 Resources 讀取到文件流信息之后,它負(fù)責(zé)解析文件流信息并構(gòu)建會話工廠 SqlSessionFactory。(解析的配置文件包含:全局配置 Configuration 與映射器 Mapper)

Mybatis最硬核的API是什么

在程序應(yīng)用端,我們一般使用 SqlSessionFactoryBuilder 直接構(gòu)建會話工廠:

// 獲得sqlSession工廠對象
SqlSessionFactory sqlSessionFactory = 
    new SqlSessionFactoryBuilder().build(resourceAsStream);

當(dāng)然,如果你集成了 Spring 框架的項(xiàng)目,則不需要自己手工去構(gòu)建會話工廠,直接在 Spring 配置文件中指定即可,例如指定一個(gè) bean 對象,id 是 sqlSessionFactory,而 class 類指定為 org.mybatis.spring.SqlSessionFactoryBean 。

SqlSessionFactoryBuilder 內(nèi)部通過解析器 XMLConfigBuilder 解析了文件流,同時(shí)封裝成為配置對象 Configuration ,再把 Configuration 對象進(jìn)行傳遞并構(gòu)建實(shí)例。

public SqlSessionFactory build(
    InputStream inputStream, 
    String environment, 
    Properties properties) {
   
     
      // 配置解析器解析
      XMLConfigBuilder parser = 
          new XMLConfigBuilder(
          	inputStream,environment, properties);
    
      // 最終實(shí)例會話工廠
      return build(parser.parse()); 
    
}

最終實(shí)例會話工廠,其實(shí) Mybatis 默認(rèn)實(shí)現(xiàn)是 new 了一個(gè)DefaultSqlSessionFactory 實(shí)例。

// 最終實(shí)例會話工廠
public SqlSessionFactory build(Configuration config) {
   
    return new DefaultSqlSessionFactory(config);
}

會話工廠構(gòu)建器 SqlSessionFactoryBuilder 應(yīng)用了構(gòu)建者模式,主要目的就是為了構(gòu)建 SqlSessionFactory 對象,以便后續(xù)生產(chǎn) SqlSession 對象,這個(gè)構(gòu)造器基本上算是 Mybatis 框架的入口構(gòu)建器,它提供了一系列多態(tài)方法 build(),支持用戶使用 XML 配置文件或 Java API (Properties)來構(gòu)建會話工廠 SqlSessionFactory 實(shí)例。

SqlSessionFactoryBuilder 的一生只為成就 SqlSessionFactory,當(dāng) SqlSessionFactory 一經(jīng)實(shí)例,SqlSessionFactoryBuilder 使命完成,便可消亡,便可被丟棄。

Mybatis最硬核的API是什么

因此 SqlSessionFactoryBuilder 實(shí)例的最佳作用域是 方法作用域(也就是局部方法變量)。 你可以重用 SqlSessionFactoryBuilder 來創(chuàng)建多個(gè) SqlSessionFactory 實(shí)例,但最好不要一直保留著它,以保證所有的 XML 解析資源可以被釋放給更重要的事情。

SqlSessionFactoryBuilder 中靈活構(gòu)建會話工廠的一系列接口:

Mybatis最硬核的API是什么

Mybatis最硬核的API是什么

5、SqlSessionFactory – 會話工廠

會話工廠 SqlSessionFactory 是一個(gè)接口,作用是生產(chǎn)數(shù)據(jù)庫會話對象 SqlSession ,有兩個(gè)實(shí)現(xiàn)類:

  • **DefaultSqlSessionFactory **(默認(rèn)實(shí)現(xiàn))

  • **SqlSessionManager **(僅多實(shí)現(xiàn)了一個(gè) Sqlsession 接口,已棄用)

在介紹會話工廠構(gòu)建器 SqlSessionFactoryBuilder 的時(shí)候,我們了解到構(gòu)建器默認(rèn)創(chuàng)建了 DefaultSqlSessionFactory 實(shí)例,并且會話工廠本身會綁定一個(gè)重要的屬性 Configuration 對象,在生產(chǎn)會話時(shí),最終也會把 Configuration 配置對象傳遞并設(shè)置到會話 SqlSession 上。

Mybatis最硬核的API是什么

會話工廠可以簡單創(chuàng)建 SqlSession 實(shí)例:

// 創(chuàng)建 SqlSession 實(shí)例
SqlSession session = sqlSessionFactory.openSession();

會話工廠創(chuàng)建 SqlSession 時(shí),會綁定數(shù)據(jù)源、事務(wù)處理、執(zhí)行器等等,默認(rèn)會話工廠實(shí)現(xiàn)類 DefaultSqlSessionFactory 在創(chuàng)建會話對象時(shí),最終都會調(diào)用 openSessionFromDataSource 方法 ,即是如此實(shí)現(xiàn):

// 每一個(gè) openSession 最終都會調(diào)用此處
private SqlSession openSessionFromDataSource(
    ExecutorType execType, 
    TransactionIsolationLevel level, 
    boolean autoCommit) {
   
    
    // 環(huán)境配置
    final Environment environment = 
        configuration.getEnvironment();
    
    // 事務(wù)工廠
    final TransactionFactory transactionFactory = 
        getTransactionFactoryFromEnvironment(environment);
    
    // 事務(wù)
    Transaction tx =
        transactionFactory.newTransaction(
        environment.getDataSource(), 
        level, 
        autoCommit);
    
    // 執(zhí)行器
    final Executor executor = 
        configuration.newExecutor(tx, execType);
    
    // 最終生成會話
    return new DefaultSqlSession(
          configuration, executor, autoCommit);
    
  }

另外,會話工廠其實(shí)提供了一系列接口來靈活生產(chǎn)會話 SqlSession,你可以指定:

  • 事務(wù)處理:你希望在 session 作用域中使用/開啟事務(wù)作用域(也就是不自動提交事務(wù)),還是使用自動提交(auto-commit),sqlSession 默認(rèn)不提交事務(wù),對于增刪改操作時(shí)需要手動提交事務(wù)。

  • 數(shù)據(jù)庫連接:你希望 MyBatis 幫你從已配置的數(shù)據(jù)源獲取連接,還是使用自己提供的連接,可以動態(tài)創(chuàng)建數(shù)據(jù)源對象 Connection。

  • 執(zhí)行器類型:你希望指定某類執(zhí)行器來創(chuàng)建/執(zhí)行/預(yù)處理語句,可以有普通執(zhí)行器(SimpleExecutor),或復(fù)用執(zhí)行器(ReuserExecutor)、還是批量執(zhí)行器(BatchExecutor)等,下面介紹執(zhí)行器時(shí)會詳細(xì)說明。

  • 事務(wù)隔離級別支持:支持 JDBC 的五個(gè)隔離級別(NONE、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ 和 SERIALIZABLE),對于事務(wù)相關(guān)的內(nèi)容,我們后續(xù) 《spring 系列全解》 會詳細(xì)講,這里簡單說明一下就是事務(wù)隔離級別主要為了解決例如臟讀、不可重復(fù)讀、幻讀等問題,使用不同的事務(wù)隔離級別勢必會導(dǎo)致不同的數(shù)據(jù)庫執(zhí)行效率,因此我們再不同的系統(tǒng)/功能中,對隔離級別有不同的需求。

Mybatis最硬核的API是什么

SqlSessionFactory 一旦被創(chuàng)建就應(yīng)該在 應(yīng)用的運(yùn)行期間 一直存在,沒有任何理由丟棄它或重新創(chuàng)建另一個(gè)實(shí)例。 使用 SqlSessionFactory 的最佳實(shí)踐是在應(yīng)用運(yùn)行期間不要重復(fù)創(chuàng)建多次,多次重建 SqlSessionFactory 被視為一種代碼“壞習(xí)慣”。因此 SqlSessionFactory 的最佳作用域是 應(yīng)用作用域。 最簡單的就是使用單例模式或者靜態(tài)單例模式。

請記住,創(chuàng)建 SqlSessionFactory ,一次就好!

每個(gè)數(shù)據(jù)庫對應(yīng)一個(gè) SqlSessionFactory 實(shí)例。SqlSessionFactory 一旦被創(chuàng)建, 它的生命周期應(yīng)該與應(yīng)用的生命周期相同 。所以,如果你想連接兩個(gè)數(shù)據(jù)庫,就需要?jiǎng)?chuàng)建兩個(gè) SqlSessionFactory 實(shí)例,每個(gè)數(shù)據(jù)庫對應(yīng)一個(gè);而如果是三個(gè)數(shù)據(jù)庫,就需要三個(gè)實(shí)例,依此類推。

Mybatis最硬核的API是什么

Mybatis最硬核的API是什么

6、SqlSession – 會話

SqlSession 是一個(gè)接口,有兩個(gè)實(shí)現(xiàn)類:

  • DefaultSqlSession(默認(rèn)實(shí)現(xiàn))

  • SqlSessionManager (已棄用)

簡單來說,通過會話工廠構(gòu)建出 SqlSession 實(shí)例之后,我們就可以進(jìn)行增刪改查了,默認(rèn)實(shí)例 DefaultSqlSession 提供了如此多的方法供用戶使用,有超過30個(gè):

Mybatis最硬核的API是什么

sqlSession 的方法除了 CURD,還提供了事務(wù)的控制例如提交/關(guān)閉/回滾等、提供了配置對象的獲取例如 getConfiguration()、提供了批量語句的執(zhí)行更新例如 flushStatements()、提供了緩存清除例如 clearCache() 、提供了映射器的使用 getMapper() 等等。

Mybatis最硬核的API是什么

對于客戶端應(yīng)用層面來說,熟悉 sqlSession 的 API 基本就可以任意操作數(shù)據(jù)庫了,不過我們希望想進(jìn)一步了解 sqlSession 內(nèi)部是如何執(zhí)行 sql 呢?其實(shí) sqlSession 是 Mybatis 中用于和數(shù)據(jù)庫交互的 頂層類,通常將它與本地線程 ThreadLocal 綁定,一個(gè)會話使用一個(gè) SqlSession,并且在使用完畢之后進(jìn)行 關(guān)閉

之所以稱 SqlSession 為數(shù)據(jù)交互的 頂層類,是它其實(shí)沒有完成實(shí)質(zhì)的數(shù)據(jù)庫操作。根據(jù)之前的架構(gòu)設(shè)計(jì)流程我們已經(jīng)清晰的知道,SqlSession 對數(shù)據(jù)庫的操作都會轉(zhuǎn)發(fā)給具體的執(zhí)行器 Executor 來完成 ;當(dāng)然執(zhí)行器也是甩手掌柜,執(zhí)行器 Executor 會再分派給語句處理器 StatementHandler ,語句處理器會結(jié)合參數(shù)處理器 ParameterHandler ,共同完成最終的數(shù)據(jù)庫執(zhí)行處理操作(底層還是封裝了 JDBC Statement 操作)。并在每個(gè)語句處理器 StatementHandler 處理完成數(shù)據(jù)庫操作之后, 通過結(jié)果結(jié)處理器 ResultSetHandler 以及類型處理器 TypeHandler ,對底層 JDBC 返回的結(jié)果集進(jìn)行映射封裝,最終才返回預(yù)期的封裝對象。

關(guān)注以下圖示 sqlSession 紅色高亮位置,詳細(xì)描述了會話的實(shí)際執(zhí)行路徑:

Mybatis最硬核的API是什么

SqlSession 可以理解為一次數(shù)據(jù)庫會話,一次會話當(dāng)中既可以執(zhí)行一次 sql ,也允許你批量執(zhí)行多次,但是一旦會話關(guān)閉之后想要再執(zhí)行 sql,那就必須重新創(chuàng)建會話。

Mybatis最硬核的API是什么

每個(gè)線程都應(yīng)該有它自己的 SqlSession 實(shí)例,SqlSession 的實(shí)例不是線程安全的,因此是不能被共享的,所以它的最佳的作用域是 請求(request)或方法(method) 作用域。 絕對不能將 SqlSession 實(shí)例的引用放在一個(gè)類的靜態(tài)域,甚至一個(gè)類的實(shí)例變量也不行。 也絕不能將 SqlSession 實(shí)例的引用放在任何類型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你現(xiàn)在正在使用一種 Web 框架,考慮將 SqlSession 放在一個(gè)和 HTTP 請求相似的作用域中。 換句話說,每次收到 HTTP 請求,就可以打開一個(gè) SqlSession,返回一個(gè)響應(yīng)后,就關(guān)閉它。 這個(gè)關(guān)閉操作很重要,為了確保每次都能執(zhí)行關(guān)閉操作,你應(yīng)該把這個(gè)關(guān)閉操作放到 finally 塊中。

Spring 集成 Mybatis 之后,通過依賴注入可以創(chuàng)建線程安全的、基于事務(wù)的 SqlSession ,并管理他們的生命周期,推薦搭配使用。

Mybatis最硬核的API是什么

7、Executor – 執(zhí)行器

Executor 是一個(gè)執(zhí)行器接口,是 Mybatis 的調(diào)度核心,它定義了一組管理 Statement 對象與獲取事務(wù)的方法,并負(fù)責(zé) SQL 語句的生成和一級/二級查詢緩存的維護(hù)等,SqlSessionFactory 在創(chuàng)建 SqlSession 時(shí)會同時(shí)創(chuàng)建執(zhí)行器,并指定執(zhí)行器類型,默認(rèn)使用 SimpleExecutor 。執(zhí)行器接口有5個(gè)子孫實(shí)現(xiàn)類,其中 BaseExecutor 是抽象類,另外4個(gè)子孫實(shí)現(xiàn)類分別是:SimpleExecutor 、BatchExecutor、ReuseExecutor、CachingExecutor。

Mybatis最硬核的API是什么

  • BaseExecutor:基礎(chǔ)執(zhí)行器(抽象類),對Executor接口進(jìn)行了基本實(shí)現(xiàn),為下一級實(shí)現(xiàn)類執(zhí)行器提供基礎(chǔ)支持。BaseExecutor 有三個(gè)子類分別是 SimpleExecutor、ResuseExecutor、BatchExecutor。

  • SimpleExecutor:普通執(zhí)行器,繼承 BaseExecutor 抽象類,是 MyBatis 中 默認(rèn) 使用的執(zhí)行器. 每執(zhí)行一次 update 或 select ,就開啟一個(gè) Statement 對象,用完立刻關(guān)閉 Statement 對象。(可以是 Statement 或 PrepareStatement 對象)。

  • ReuseExecutor:復(fù)用執(zhí)行器,繼承 BaseExecutor 抽象類,這里的復(fù)用指的是重復(fù)使用 Statement . 它會在內(nèi)部利用一個(gè) Map 把創(chuàng)建的 Statement 都緩存起來,每次在執(zhí)行一條 SQL語 句時(shí),它都會去判斷之前是否存在基于該 SQL 緩存的 Statement 對象,存在且之前緩存的 Statement 對象對應(yīng)的 Connection 還沒有關(guān)閉則會繼續(xù)使用之前的 Statement 對象,否則將創(chuàng)建一個(gè)新的 Statement 對象,并將其緩存起來。因?yàn)槊恳粋€(gè)新的 SqlSession 都有一個(gè)新的 Executor 對象,所以我們緩存在 ReuseExecutor 上的 Statement 的作用域是同一個(gè) SqlSession 。

  • BatchExecutor:批處理執(zhí)行器,繼承 BaseExecutor 抽象類,通過批量操作來提高性能,用于將多個(gè) sql 語句一次性輸送到數(shù)據(jù)庫執(zhí)行。由于內(nèi)部有緩存的實(shí)現(xiàn),所以使用完成后需要調(diào)用 flushStatements() 來清除緩存。

  • CachingExecutor : 緩存執(zhí)行器,繼承 BaseExecutor 抽象類,它為 Executor 對象增加了 二級緩存 的相關(guān)功能,cachingExecutor 有一個(gè)重要屬性 delegate,即為委托的執(zhí)行器對象,可以是 SimpleExecutor、ReuseExecutor、BatchExecutor 中任意一個(gè)。CachingExecutor 在執(zhí)行數(shù)據(jù)庫 update 操作時(shí),它直接調(diào)用 委托對象 delegate 的 update 方法;而執(zhí)行查詢時(shí),它會先從緩存中獲取查詢結(jié)果,存在就返回,不存在則委托 delegate 去數(shù)據(jù)庫取,然后存儲到緩存 cache 中。

Mybatis 在構(gòu)建 Configuration 配置類時(shí)默認(rèn)把 ExecutorType.SIMPLE 作為執(zhí)行器類型,當(dāng)我們的會話工廠 DefaultSqlSessionFactory 開始生產(chǎn) SqlSession 會話時(shí),會同時(shí)構(gòu)建執(zhí)行器,此時(shí)就會依據(jù)配置類 Configuration 構(gòu)建時(shí)指定的執(zhí)行器類型來實(shí)例具體執(zhí)行器 ,流程如下:

// 1、Configuration配置類構(gòu)建時(shí)
// 指定了默認(rèn)執(zhí)行器類型為:普通執(zhí)行器
protected ExecutorType defaultExecutorType 
    = ExecutorType.SIMPLE;

// 2、Configuration配置類中
// 提供方法獲取默認(rèn)執(zhí)行器類型
public ExecutorType getDefaultExecutorType() {
   
    return defaultExecutorType;
}

// 3、會話工廠創(chuàng)建 SqlSession 實(shí)例時(shí)
SqlSession session = sqlSessionFactory.openSession();

// 4、openSession 實(shí)際邏輯
public SqlSession openSession() {
   
    return 
       openSessionFromDataSource(
           // 這里可就獲取了默認(rèn)執(zhí)行器
           configuration.getDefaultExecutorType(), 
           null, 
           false
        );
}

這里,肯定有人想知道,我們能否指定其它執(zhí)行器呢?

答案是:當(dāng)然可以,有兩種方式指定:

  • 第一種方式是通過 Java API 指定,在開啟會話 openSession 時(shí)進(jìn)行指定。例如:

// 創(chuàng)建 SqlSession 實(shí)例
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.REUSE)
    
// ExecutorType是一個(gè)枚舉
// 有三個(gè)值SIMPLE, REUSE, BATCH
  • 另一種通過 Configuration 配置方式來指定默認(rèn)執(zhí)行器類型。例如

<settings>
    <!--取值范圍 SIMPLE, REUSE, BATCH -->
	<setting name="defaultExecutorType" value="REUSE"/>
</settings>

對于第二種 settings 的配置方式,其實(shí)之前我們在介紹 Mybatis 的配置文件中已經(jīng)講過,這里再簡單說明一下,像上面配置 settings 中的屬性 defaultExecutorType ,基本這些屬性都是 Mybatis 額外提供給我們靈活設(shè)置的,就算我們不設(shè)置 Mybatis 也會有默認(rèn)值,例如像 defaultExecutorType 的默認(rèn)值就是 SIMPLE。你看一下 Mybatis 在解析 Configuration 配置時(shí)的默認(rèn)構(gòu)建,就會明白:

解析 Configuration 的解析器(類與具體方法的代碼路徑):

org.apache.ibatis.builder.xml.XMLConfigBuilder#settingsElement

我們截取部分代碼邏輯,下面是設(shè)置默認(rèn)執(zhí)行器類型屬性 defaultExecutorType 的內(nèi)容:

// 配置文件解析器 
public class XMLConfigBuilder {
   
    
    // 最終解析到的 Configuration 對象
    protected final Configuration configuration;
    
    // 為 Configuration 對象設(shè)置屬性
    private void settingsElement(Properties props) {
   
        
        // 設(shè)置默認(rèn)執(zhí)行器類型,默認(rèn)是 SIMPLE
        configuration.setDefaultExecutorType(
            ExecutorType.valueOf(
                props.getProperty(
                    "defaultExecutorType", "SIMPLE")));
        
        // .... 當(dāng)然這里還有很多屬性設(shè)置
        // .... 只要你在<settings>中配置即可
    
    }
}

注意,到此我們知道可以根據(jù)業(yè)務(wù)需要指定執(zhí)行器類型,例如 SIMPLE(普通執(zhí)行器), REUSE(復(fù)用執(zhí)行器), BATCH(批處理執(zhí)行器)。

但是,有朋友就好奇了,那緩存執(zhí)行器 CachingExecutor 好像不見說明呢?

確實(shí)如此,因?yàn)榫彺鎴?zhí)行器個(gè)其它三個(gè)執(zhí)行器還不太一樣,CachingExecutor 是需要我們開啟二級緩存才會有,這里大家先不要思考什么是一級緩存,什么二級緩存,后續(xù)我們有一文會詳細(xì)講緩存整個(gè)知識內(nèi)容。

大家先了解一個(gè)概念即可,就是 Mybatis 的一級緩存是默認(rèn)開啟的,不管你要不要,都會有一級緩存,而二級緩存呢,是默認(rèn)關(guān)閉的,但允許我們手工開啟。

對比開啟二級緩存前后,執(zhí)行器執(zhí)行的區(qū)別吧!

  • 不開啟二級緩存,執(zhí)行器執(zhí)行時(shí)

Mybatis最硬核的API是什么

  • 開啟二級緩存之后,執(zhí)行器執(zhí)行時(shí)

Mybatis最硬核的API是什么

其實(shí)我們實(shí)際操作數(shù)據(jù)庫,不會直接接觸到執(zhí)行器 Executor ,不過我們確實(shí)可以了解一下基本的執(zhí)行原理,下面列出了執(zhí)行器接口提供的眾多重載方法,基本用于事務(wù)/緩存/數(shù)據(jù)庫管理與訪問,可以知道一下:

Mybatis最硬核的API是什么

到此,對于執(zhí)行器有了基本的認(rèn)識,但是實(shí)際上,我們知道執(zhí)行器自身沒有去具體執(zhí)行 SQL 語句,而是分派到語句處理器 StatementHandler ,語句處理器會結(jié)合參數(shù)處理器 ParameterHandler ,最終進(jìn)行數(shù)據(jù)庫操作。

Mybatis最硬核的API是什么

8、StatementHandler – 語句處理器

StatementHandler 是一個(gè)語句處理器接口,它封裝了 JDBC Statement 操作,負(fù)責(zé)對 JDBC Statement 的操作,如 設(shè)置參數(shù)、結(jié)果集映射,是實(shí)際跟數(shù)據(jù)庫做交互的一道。StatementHandler 語句處理器實(shí)例,是在執(zhí)行器具體執(zhí)行 CRUD 操作時(shí)構(gòu)建的,默認(rèn)使用 PrepareStatementHandler。語句處理器接口有5個(gè)子孫實(shí)現(xiàn)類,其中 BaseStatementHandler 是抽象類,另外4個(gè)子孫實(shí)現(xiàn)類分別是:SimpleStatementHandler、PrepareStatementHandler、CallableStatementHandler、RoutingStatementHandler。

Mybatis最硬核的API是什么

  • BaseStatementHandler:基礎(chǔ)語句處理器(抽象類),它基本把語句處理器接口的核心部分都實(shí)現(xiàn)了,包括配置綁定、執(zhí)行器綁定、映射器綁定、參數(shù)處理器構(gòu)建、結(jié)果集處理器構(gòu)建、語句超時(shí)設(shè)置、語句關(guān)閉等,并另外定義了新的方法 instantiateStatement 供不同子類實(shí)現(xiàn)以便獲取不同類型的語句連接,子類可以普通執(zhí)行 SQL 語句,也可以做預(yù)編譯執(zhí)行,還可以執(zhí)行存儲過程等。

  • SimpleStatementHandler:普通語句處理器,繼承 BaseStatementHandler 抽象類,對應(yīng) java.sql.Statement 對象的處理,處理普通的不帶動態(tài)參數(shù)運(yùn)行的 SQL,即執(zhí)行簡單拼接的字符串語句,同時(shí)由于 Statement 的特性,SimpleStatementHandler 每次執(zhí)行都需要編譯 SQL (注意:我們知道 SQL 的執(zhí)行是需要編譯和解析的)。

  • PreparedStatementHandler:預(yù)編譯語句處理器,繼承 BaseStatementHandler 抽象類,對應(yīng) java.sql.PrepareStatement 對象的處理,相比上面的普通語句處理器,它支持可變參數(shù) SQL 執(zhí)行,由于 PrepareStatement 的特性,它會進(jìn)行預(yù)編譯,在緩存中一旦發(fā)現(xiàn)有預(yù)編譯的命令,會直接解析執(zhí)行,所以減少了再次編譯環(huán)節(jié),能夠有效提高系統(tǒng)性能,并預(yù)防 SQL 注入攻擊(所以是系統(tǒng)默認(rèn)也是我們推薦的語句處理器)。

  • CallableStatementHandler:存儲過程處理器,繼承 BaseStatementHandler 抽象類,對應(yīng) java.sql.CallableStatement 對象的處理,很明了,它是用來調(diào)用存儲過程的,增加了存儲過程的函數(shù)調(diào)用以及輸出/輸入?yún)?shù)的處理支持。

其實(shí)普通語句處理器、預(yù)執(zhí)行語句處理器以及存儲過程處理器,只是 Mybatis 對于 JDBC 的語句執(zhí)行對象的簡單包裝而已,沒有特別神秘,看以下 JDBC 的語句執(zhí)行對象的類圖關(guān)系也就能夠清楚。

  • RoutingStatementHandler:路由語句處理器,直接實(shí)現(xiàn)了 StatementHandler 接口,作用如其名稱,確確實(shí)實(shí)只是起到了路由功能,并把上面介紹到的三個(gè)語句處理器實(shí)例作為自身的委托對象而已,所以執(zhí)行器在構(gòu)建語句處理器時(shí),都是直接 new 了 RoutingStatementHandler 實(shí)例。

// 1、執(zhí)行器構(gòu)建語句處理器實(shí)例
public StatementHandler newStatementHandler(...) {
   
    
    // 構(gòu)建路由語句處理器即可!
    StatementHandler statementHandler = 
        new RoutingStatementHandler(...);
    
    // 其它邏輯忽略...
    return statementHandler;
}

// 2、實(shí)際構(gòu)造方法(路由關(guān)系)
public RoutingStatementHandler(...) {
   

    // 根據(jù)指定類型構(gòu)造委托實(shí)例
    switch (ms.getStatementType()) {
   
      case STATEMENT:
        delegate = new SimpleStatementHandler(...);
        break;
      case PREPARED:
        delegate = new PreparedStatementHandler(...);
        break;
      case CALLABLE:
        delegate = new CallableStatementHandler(...);
        break;
      default:
        throw new ExecutorException(
            "Unknown statement type: " 
                + ms.getStatementType());
    }
}

我們前面介紹了執(zhí)行器具體執(zhí)行 CRUD 操作時(shí),構(gòu)造的語句處理器默認(rèn)使用 PrepareStatementHandler ,不過有些好奇的腦袋就想問問,那我們能不能指定語句處理器類型呢?

當(dāng)然可以,例如我們指定更新用戶語句適用預(yù)編譯處理語句處理器:

<!--取值范圍 STATEMENT, PREPARED, CALLABLE -->
<update id="updateUser" statementType="STATEMENT">
    update t_user set name = #{newName}
</update>

當(dāng) Mybatis 在解析映射器中的每條語句時(shí),會設(shè)置語句處理器類型:

// 語句對象解析器 
public class XMLStatementBuilder {
   
    
    // 解析語句節(jié)點(diǎn)
    public void parseStatementNode() {
    
        
        // 設(shè)置語句處理器類型
        // 默認(rèn)是 PREPARED 類型
        StatementType statementType = 
         StatementType.valueOf(
            context.getStringAttribute(
                "statementType", 
                StatementType.PREPARED.toString()
            )
        ); 
    }  
}

所以,語句執(zhí)行器與數(shù)據(jù)庫的交互過程:

Mybatis最硬核的API是什么

當(dāng)然,語句處理器接口 StatementHandler 提供了基本接口,一般我們沒必要自定義實(shí)現(xiàn)類,所以可以簡單看一下即可:

Mybatis最硬核的API是什么

Mybatis最硬核的API是什么

9、ParamerHandler – 參數(shù)處理器

ParameterHandler 是一個(gè)參數(shù)處理器接口,它負(fù)責(zé)把用戶傳遞的參數(shù)轉(zhuǎn)換成 JDBC Statement 所需要的參數(shù),底層做數(shù)據(jù)轉(zhuǎn)換的工作會交給類型轉(zhuǎn)換器 TypeHandler,后面會介紹。

很顯然,需要對傳入的參數(shù)進(jìn)行轉(zhuǎn)換處理的 StatementHandler 實(shí)例只有兩個(gè),分別是:

  • PrepareStatementHandler 預(yù)編譯處理器

  • CallableStatementHandler 存儲過程處理器

上面在介紹語句處理器的時(shí)候,我們有介紹說基礎(chǔ)語句處理器 BaseStatementHandler 在進(jìn)行實(shí)例構(gòu)建時(shí),會同時(shí)構(gòu)建參數(shù)處理器與結(jié)果集處理器,所以參數(shù)處理器就是在此時(shí)被構(gòu)建。

// 基礎(chǔ)語句處理器
public abstract class BaseStatementHandler{
   
    
    // 構(gòu)造實(shí)例時(shí)
    protected BaseStatementHandler(...){
   
        
        // 其它邏輯可忽略...
        
        // 1、構(gòu)建參數(shù)處理器
        this.parameterHandler = 
            conf.newParameterHandler(...);
    	
        // 2、構(gòu)建結(jié)果集處理器
        this.resultSetHandler = 
        	conf.newResultSetHandler(...);
    } 
}

對于參數(shù)處理器接口,相對簡單,只有1個(gè)默認(rèn)實(shí)現(xiàn)類 DefaultParameterHandler ,該接口只有兩個(gè)方法,分別是:

Mybatis最硬核的API是什么

  • 1、setParameters 設(shè)置參數(shù),發(fā)生在 CURD 語句執(zhí)行時(shí),語句處理器設(shè)置參數(shù)

// 有2個(gè)處理器會使用,分別是:
// 預(yù)編譯處理器 PreparedStatementHandler
// 存儲過程處理器 CallableStatementHandler

public void parameterize(Statement statement) {
   
    
    //使用ParameterHandler對象來完成對Statement的設(shè)值
    parameterHandler.setParameters(statement);
}

應(yīng)用場景例如查詢用戶對象時(shí),設(shè)置姓名,參數(shù)處理器結(jié)合類型處理器把 name 屬性占位符進(jìn)行賦值。

<select id="queryUSer">
    select * from t_user where name = #{name}
</select>
  • 2、getParameterObject 獲取參數(shù),發(fā)生在結(jié)果集返回時(shí),結(jié)果集處理器獲取對象參數(shù),值得注意的時(shí),該方法只用于存儲過程處理器 CallableStatementHandler 。

// 默認(rèn)結(jié)果集處理器
public class DefaultResultSetHandler{
   
   
    // 處理輸出參數(shù)
    public void handleOutputParameters(...) {
   
    
        // 獲取參數(shù)
        final Object parameterObject = 
            parameterHandler.getParameterObject();
    
    	// 其它存儲過程輸出參數(shù)處理邏輯...
	}    
}

Mybatis最硬核的API是什么

10、ResultSetHandler – 結(jié)果集處理器

ResultSetHandler 是一個(gè)結(jié)果集處理器接口,它負(fù)責(zé)負(fù)責(zé)將 JDBC 返回的結(jié)果集 resultSet 對象轉(zhuǎn)換為 List 類型的集合,是在語句處理器構(gòu)建實(shí)例時(shí)被同時(shí)創(chuàng)建,底層做數(shù)據(jù)轉(zhuǎn)換的工作會交給類型轉(zhuǎn)換器 TypeHandler,它有1個(gè)默認(rèn)實(shí)現(xiàn)類 DefaultResultSetHandler,該接口有3個(gè)方法,分別是:

Mybatis最硬核的API是什么

  • handleResultSets:負(fù)責(zé)結(jié)果集處理,完成映射返回結(jié)果對象

  • handleCursorResultSets :負(fù)責(zé)游標(biāo)對象處理

  • handleOutputParameters :負(fù)責(zé)存儲過程的輸出參數(shù)處理

結(jié)果集處理器對于 JDBC 返回的結(jié)果集的基本處理,是先獲取我們在映射器 Mapper 中指定 resultType 或 resultMap 映射關(guān)系,然后遍歷解析結(jié)果集中的每一列數(shù)據(jù),底層通過 MetaObject 對象做相關(guān)的反射處理。

對于詳細(xì)的源碼邏輯,我們后續(xù)源碼剖析部分詳細(xì)講。

不講不是中國人 O(∩_∩)O ~

Mybatis最硬核的API是什么

11、TypeHandler – 類型轉(zhuǎn)換器

TypeHandler 是一個(gè)類型轉(zhuǎn)換器/處理器接口,它負(fù)責(zé) Java 數(shù)據(jù)類型和 JDBC 數(shù)據(jù)類型之間的映射與轉(zhuǎn)換,當(dāng)對 Statement 對象設(shè)置參數(shù)時(shí),由 JavaType 轉(zhuǎn)換為 JdbcType,當(dāng)對 Statement 返回結(jié)果集進(jìn)行封裝映射時(shí),又會將 JdbcType 轉(zhuǎn)換為 JavaType。

Mybatis最硬核的API是什么

一般,我們可以直接使用 Mybatis 內(nèi)置的類型處理器,簡單看了一下有 65+ 個(gè),當(dāng)然我們是可以根據(jù)業(yè)務(wù)需要自定義類型處理器的,以便處理復(fù)雜類型或非標(biāo)類型。

具體做法為:

1、實(shí)現(xiàn) org.apache.ibatis.type.TypeHandler 接口;

2、繼承 org.apache.ibatis.type.BaseTypeHandler 類。

其中 BaseTypeHandler 類作為抽象類就已經(jīng)實(shí)現(xiàn)了 TypeHandler 接口。

我們看到接口 TypeHandler 定義了四個(gè)方法:

public interface TypeHandler<T> {
   

  // 設(shè)置參數(shù)
  void setParameter(
      PreparedStatement ps, 
      int i, T parameter, 
      JdbcType jdbcType);

  // 根據(jù)列名獲取轉(zhuǎn)換結(jié)果
  T getResult(ResultSet rs, String columnName);

  // 根據(jù)列下標(biāo)獲取轉(zhuǎn)換結(jié)果
  T getResult(ResultSet rs, int columnIndex);

  // 根據(jù)列下標(biāo)獲取【存儲過程】的輸出結(jié)果
  T getResult(CallableStatement cs, int columnIndex);

}

其實(shí),我之前在介紹 Mybatis 核心配置的時(shí)候,有大力介紹過類型處理器,沒必要重復(fù)寫(其實(shí)是懶),感興趣的朋友可以直接看我們之前的文章 **《Mybatis系列全解(四):全網(wǎng)最全!Mybatis配置文件XML全貌詳解》**中對類型處理器 TypeHandler 的介紹。

Mybatis最硬核的API是什么

12、MappedStatement – 語句對象

MappedStatement 語句對象,就是我們在映射器 Mapper 中維護(hù)的每一條語句,例如 <select|update|delete|insert>,Mybatis 中通過語句構(gòu)造器 XMLStatementBuilder 對每一個(gè)語句進(jìn)行解析:

Mybatis最硬核的API是什么

整個(gè)解析過程分為4步驟:

  • 1、配置解析器 XMLConfigBuilder 解析映射器:

// Configuration 配置解析器
public class XMLConfigBuilder{
   
    
    // 解析映射器
    private void mapperElement(){
   
        
        // 創(chuàng)建映射器解析實(shí)例
        XMLMapperBuilder mapperParser = 
            new XMLMapperBuilder(...);
        
        // 開始解析
        mapperParser.parse();
    }
}

2、映射對象解析器 XMLMapperBuilder 解析語句

// 映射對象解析器
public class XMLMapperBuilder{
   
    
    // 1、解析入口
    public void parse() {
    
        
        // 解析映射器文件
        configurationElement(
            parser.evalNode("/mapper"));
    }
    
    // 2、節(jié)點(diǎn)解析
    private void configurationElement(XNode context) {
   
        
        // 構(gòu)建語句對象
        buildStatementFromContext(
            context.evalNodes(
                "select|insert|update|delete"));
    }
    
    // 3、最終調(diào)用語句解析器
    private void buildStatementFromContext(){
   
        
        // 創(chuàng)建語句解析實(shí)例
        XMLStatementBuilder statementParser = 
            new XMLStatementBuilder();
        
        // 解析語句節(jié)點(diǎn)
        statementParser.parseStatementNode();
    }
}

3、語句解析器 XMLStatementBuilder 解析每一個(gè)節(jié)點(diǎn)

// 語句解析器
public class XMLStatementBuilder{
   
    
    // 解析語句節(jié)點(diǎn)
    public void parseStatementNode() {
   
        
        // 通過語句輔助類構(gòu)建語句對象
        builderAssistant.addMappedStatement(...)
    }
}

4、語句輔助類 MapperBuilderAssistant 添加進(jìn)語句集合中

// 語句輔助類
public class MapperBuilderAssistant{
   
    
    // 添加語句對象
    public MappedStatement addMappedStatement(
         
        // 最終添加到配置類的語句集合中
    	configuration.addMappedStatement(statement);
    }
}

Mybatis最硬核的API是什么

13、SqlSource – SQL源

SqlSource 是一個(gè) SQL 源接口,它會結(jié)合用戶傳遞的參數(shù)對象 parameterObject,動態(tài)地生成 SQL 語句,并最終封裝成 BoundSql 對象。SqlSource 接口有5個(gè)實(shí)現(xiàn)類,分別是:StaticSqlSource、DynamicSqlSource、RawSqlSource、ProviderSqlSource、VelocitySqlSource(這只是一個(gè)測試用例,而非真正模板 Sql 源實(shí)現(xiàn)類)。

Mybatis最硬核的API是什么

  • StaticSqlSource:靜態(tài) SQL 源實(shí)現(xiàn)類,所有的 SQL 源最終都會構(gòu)建 StaticSqlSource 實(shí)例,該實(shí)現(xiàn)類會生成最終可執(zhí)行的 SQL 語句供 statement 或 prepareStatement 使用。

  • RawSqlSource:原生 SQL 源實(shí)現(xiàn)類,解析構(gòu)建含有 ‘#{}’ 占位符的 SQL 語句或原生 SQL 語句,解析完最終會構(gòu)建 StaticSqlSource 實(shí)例。

  • DynamicSqlSource:動態(tài) SQL 源實(shí)現(xiàn)類,解析構(gòu)建含有 ‘${}’ 替換符的 SQL 語句或含有動態(tài) SQL 的語句(例如 If/Where/Foreach等),解析完最終會構(gòu)建 StaticSqlSource 實(shí)例。

  • ProviderSqlSource:注解方式的 SQL 源實(shí)現(xiàn)類,會根據(jù) SQL 語句的內(nèi)容分發(fā)給 RawSqlSource 或 DynamicSqlSource ,當(dāng)然最終也會構(gòu)建 StaticSqlSource 實(shí)例。

  • VelocitySqlSource:模板 SQL 源實(shí)現(xiàn)類,官方申明這只是一個(gè)測試用例,而非真正的模板 Sql 源實(shí)現(xiàn)類。

SqlSource 實(shí)例在配置類 Configuration 解析階段就被創(chuàng)建,Mybatis 框架會依據(jù)3個(gè)維度的信息來選擇構(gòu)建哪種數(shù)據(jù)源實(shí)例:

  • 第一個(gè)維度:客戶端的 SQL 配置方式:XML 方式或者注解方式。

  • 第二個(gè)維度:SQL 語句中是否使用動態(tài) SQL ( if/where/foreach 等 )。

  • 第三個(gè)維度:SQL 語句中是否含有替換符 ‘${}’ 或占位符 ‘#{}’ 。

SqlSource 接口只有一個(gè)方法 getBoundSql ,就是創(chuàng)建 BoundSql 對象。

public interface SqlSource {
   

  BoundSql getBoundSql(Object parameterObject);

}

Mybatis最硬核的API是什么

14、BoundSql – SQL語句

BoundSql 對象存儲了動態(tài)生成的 SQL 語句以及相應(yīng)的參數(shù)信息,BoundSql 對象是在執(zhí)行器具體執(zhí)行 CURD 時(shí)通過實(shí)際的 SqlSource 實(shí)例所構(gòu)建。通過 BoundSql 能夠獲取到實(shí)際數(shù)據(jù)庫執(zhí)行的 SQL 語句,系統(tǒng)可根據(jù) SQL 語句構(gòu)建 Statement 或者 PrepareStatement 。

public class BoundSql {
   

  //該字段中記錄了SQL語句,該SQL語句中可能含有"?"占位符
  private final String sql;
    
  //SQL中的參數(shù)屬性集合
  private final List<ParameterMapping> parameterMappings;
    
  //客戶端執(zhí)行SQL時(shí)傳入的實(shí)際參數(shù)值
  private final Object parameterObject;
    
  //復(fù)制 DynamicContext.bindings 集合中的內(nèi)容
  private final Map<String, Object> additionalParameters;
    
  //通過 additionalParameters 構(gòu)建元參數(shù)對象
  private final MetaObject metaParameters;
    
}

到此,相信大家對“Mybatis最硬核的API是什么”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI