MyBatis SqlSessionFactory 是如何創建的?

SqlSessionFactory 是 MyBatis 的核心接口之一,它是創建 SqlSession 實例的工廠。 SqlSession 實例是 MyBatis 與數據庫交互的主要接口,負責執行 SQL 語句、管理事務等。

SqlSessionFactory 的創建過程主要由 SqlSessionFactoryBuilder 類負責。 SqlSessionFactoryBuilder 遵循建造者模式,提供多種構建 SqlSessionFactory 的方法,可以從不同的配置源 (如 XML 配置文件、Java 代碼配置) 構建 SqlSessionFactory 實例。

以下是 SqlSessionFactory 的詳細創建步驟,以及涉及的關鍵類和方法:

1. 獲取 MyBatis 配置信息 (Configuration Source):

在創建 SqlSessionFactory 之前,首先需要加載和解析 MyBatis 的配置信息。 MyBatis 配置信息可以來源于以下幾種方式:

  • XML 配置文件 (mybatis-config.xml 或自定義 XML 文件): 這是最常見的配置方式,通過 XML 文件定義 MyBatis 的全局配置、數據源、事務管理器、Mapper 映射文件等。
  • Java 代碼配置 (使用 Configuration 類): 也可以使用 Java 代碼直接構建 Configuration 對象,并設置各種配置項。
  • Spring 集成 (Spring Boot 或 Spring Framework): 當 MyBatis 與 Spring 集成時,Spring 容器會負責管理 SqlSessionFactory 的創建和生命周期,配置信息通常由 Spring 管理。

2. 使用 SqlSessionFactoryBuilder 構建 SqlSessionFactory:

SqlSessionFactoryBuilder 類提供了多個重載的 build() 方法,用于根據不同的配置源構建 SqlSessionFactory 實例。 最常用的 build() 方法接受一個 InputStream 參數,用于讀取 XML 配置文件。

常見的 SqlSessionFactoryBuilder.build() 方法調用方式:

  • 從 XML 配置文件構建 (最常用):

    String resource = "mybatis-config.xml"; // MyBatis 配置文件路徑
    InputStream inputStream = Resources.getResourceAsStream(resource); // 使用 Resources 工具類加載資源
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    
    • Resources.getResourceAsStream(resource): MyBatis 提供的 Resources 工具類,用于從類路徑 (classpath) 或文件系統加載資源文件 (例如 XML 配置文件)。
    • new SqlSessionFactoryBuilder().build(inputStream): 創建 SqlSessionFactoryBuilder 實例,并調用 build(inputStream) 方法,傳入配置文件的 InputStreambuild() 方法會解析 XML 配置文件,并構建 SqlSessionFactory 實例。
  • Configuration 對象構建 (Java 代碼配置):

    Configuration configuration = new Configuration();
    // ... 通過 configuration 對象設置各種 MyBatis 配置,例如:
    // configuration.setEnvironment(environment);
    // configuration.addMapper(UserMapper.class);
    // ...SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
    
    • new Configuration(): 創建 Configuration 對象。
    • 通過 configuration 對象,可以使用其提供的 API 方法 (例如 setEnvironment(), addMapper(), getTypeHandlerRegistry(), getInterceptors(), getSettings(), getProperties() 等) 來設置 MyBatis 的各種配置項。
    • new SqlSessionFactoryBuilder().build(configuration): 調用 SqlSessionFactoryBuilderbuild(configuration) 方法,傳入配置好的 Configuration 對象,構建 SqlSessionFactory 實例。

3. SqlSessionFactoryBuilder.build() 方法內部的詳細步驟 (以 XML 配置為例):

SqlSessionFactoryBuilder.build(InputStream inputStream) 方法內部會執行以下關鍵步驟來創建 SqlSessionFactory

  • 3.1. 創建 XMLConfigBuilder 對象:

    XMLConfigBuilder parser = new XMLConfigBuilder(inputStream);
    
    • XMLConfigBuilder 是 MyBatis 提供的 XML 配置解析器,專門用于解析 MyBatis 的 XML 配置文件。
    • 構造 XMLConfigBuilder 時,需要傳入配置文件的 InputStream
  • 3.2. 解析 XML 配置文件并構建 Configuration 對象:

    Configuration configuration = parser.parse();
    
    • 調用 XMLConfigBuilderparse() 方法,開始解析 XML 配置文件。
    • parse() 方法會讀取 XML 配置文件中的各個元素 (例如 <configuration>, <environments>, <mappers>, <typeHandlers>, <plugins>, <settings>, <properties> 等),并根據 XML 文件的內容,構建并填充一個 Configuration 對象
    • XMLConfigBuilder.parse() 方法內部會完成以下主要工作:
      • 解析 <configuration> 根元素: 讀取 <configuration> 元素下的子元素。
      • 解析 <properties> 元素: 加載外部屬性文件或 <properties> 元素內部的屬性配置。
      • 解析 <settings> 元素: 設置 MyBatis 的全局設置,例如緩存策略、延遲加載、日志配置等。
      • 解析 <typeAliases> 元素: 定義類型別名,簡化類型名稱的使用。
      • 解析 <typeHandlers> 元素: 注冊自定義的類型處理器。
      • 解析 <objectFactory> 元素: 配置自定義的對象工廠。
      • 解析 <objectWrapperFactory> 元素: 配置自定義的對象包裝工廠。
      • 解析 <reflectorFactory> 元素: 配置自定義的反射工廠。
      • 解析 <plugins> 元素: 注冊插件 (攔截器)。
      • 解析 <environments> 元素: 配置 MyBatis 的運行環境 (例如 development, production)。
        • 解析 <environment> 元素: 配置具體的運行環境,包括 transactionManager (事務管理器) 和 dataSource (數據源)。
          • 解析 <transactionManager> 元素: 配置事務管理器 (例如 JDBC, MANAGED)。
          • 解析 <dataSource> 元素: 配置數據源 (例如 UNPOOLED, POOLED, JNDI),并設置數據源連接屬性 (例如 driver, url, username, password)。
      • 解析 <mappers> 元素: 注冊 Mapper 映射器。
        • 根據 <mapper> 元素的配置方式 (resource, url, class, package),加載 Mapper 映射文件或 Mapper 接口,并將 Mapper 信息添加到 Configuration 對象中。
          • 對于 XML Mapper 文件 (resource, url): 使用 XMLMapperBuilder 解析 Mapper XML 文件,并將 Mapper 語句 (SQL 映射) 解析到 Configuration 對象中。
          • 對于 Mapper 接口 (class, package): 將 Mapper 接口注冊到 Configuration 對象中,后續在執行 SQL 時,MyBatis 會動態地為 Mapper 接口生成代理對象。
  • 3.3. 構建 SqlSessionFactory 實例:

    return build(configuration);
    
    • XMLConfigBuilder.parse() 方法最終會返回構建好的 Configuration 對象。
    • SqlSessionFactoryBuilder.build(InputStream inputStream) 方法內部會再次調用 build(configuration) 方法,將解析得到的 Configuration 對象傳遞給它。
    • SqlSessionFactoryBuilder.build(Configuration config) 方法會真正創建 DefaultSqlSessionFactory 實例,并將 Configuration 對象作為構造參數傳入。
  • 3.4. 返回 SqlSessionFactory 實例:

    private SqlSessionFactory build(Configuration config) {return new DefaultSqlSessionFactory(config);
    }
    
    • SqlSessionFactoryBuilder.build(Configuration config) 方法會創建 DefaultSqlSessionFactory 實例,并將之前解析和構建的 Configuration 對象傳遞給 DefaultSqlSessionFactory 的構造器。
    • DefaultSqlSessionFactorySqlSessionFactory 接口的默認實現類,它內部持有 Configuration 對象,并負責創建 SqlSession 實例。
    • SqlSessionFactoryBuilder.build() 方法最終會返回創建好的 SqlSessionFactory 實例。

4. SqlSessionFactory 的生命周期:

  • SqlSessionFactory 一旦被創建,應該在應用的整個生命周期內都存在。 最佳實踐是在應用啟動時創建 SqlSessionFactory,并將其作為單例 (Singleton) 對象進行管理和使用。
  • 在 Spring 環境中,SqlSessionFactory 通常由 Spring 容器管理,聲明為 Spring Bean,并由 Spring 負責其生命周期管理。

總結 SqlSessionFactory 創建的關鍵步驟:

  1. 加載 MyBatis 配置信息 (XML 配置文件或 Java 代碼配置)。
  2. 創建 SqlSessionFactoryBuilder 實例。
  3. 調用 SqlSessionFactoryBuilder.build() 方法,傳入配置信息 (例如 InputStreamConfiguration 對象)。
  4. SqlSessionFactoryBuilder.build() 內部:
    • 創建 XMLConfigBuilder (如果使用 XML 配置)。
    • XMLConfigBuilder 解析 XML 配置文件,構建并填充 Configuration 對象。
    • SqlSessionFactoryBuilder 使用 Configuration 對象創建 DefaultSqlSessionFactory 實例。
  5. 返回 SqlSessionFactory 實例。

SqlSessionFactory 的重要性:

  • SqlSession 工廠: SqlSessionFactorySqlSession 的工廠,負責創建 SqlSession 實例。
  • 配置中心: SqlSessionFactory 內部持有 Configuration 對象,包含了 MyBatis 的所有配置信息 (數據源、事務管理器、Mapper 映射、全局設置等)。 Configuration 對象是 MyBatis 配置信息的中心倉庫。
  • 性能優化: SqlSessionFactory 是重量級對象,創建過程相對耗時,但創建后可以重復使用,避免了每次數據庫操作都重新解析配置和創建工廠的開銷。 將其作為單例管理可以提高性能。
  • 線程安全: SqlSessionFactory 本身是線程安全的,可以被多個線程共享使用。 但 SqlSession 實例不是線程安全的,每個線程應該擁有自己的 SqlSession 實例。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/73506.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/73506.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/73506.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

玩轉python:通俗易懂掌握高級數據結構-collections模塊之Counter

引言 Counter是Python中collections模塊提供的一個強大工具&#xff0c;用于統計可哈希對象的出現次數。它非常適合用于頻率統計、詞頻分析、數據聚合等場景。本文將詳細介紹Counter的關鍵用法和特性&#xff0c;并通過8個豐富的案例幫助讀者掌握其應用。 關鍵用法和特性表格 …

DeepSeek面試——分詞算法

DeepSeek-V3 分詞算法 一、核心算法&#xff1a;字節級BPE&#xff08;Byte-level BPE&#xff0c;BBPE&#xff09; DeepSeek-V3 采用 字節級BPE&#xff08;BBPE&#xff09; 作為核心分詞算法&#xff0c;這是對傳統 BPE&#xff08;Byte Pair Encoding&#xff09;算法的…

機器學習——正則化、欠擬合、過擬合、學習曲線

過擬合&#xff08;overfitting&#xff09;:模型只能擬合訓練數據的狀態。即過度訓練。 避免過擬合的幾種方法&#xff1a; ①增加全部訓練數據的數量&#xff08;最為有效的方式&#xff09; ②使用簡單的模型&#xff08;簡單的模型學不夠&#xff0c;復雜的模型學的太多&am…

Python:函數(一)

python函數相關的知識點 1. 函數定義與調用 定義&#xff1a;使用 def 關鍵字&#xff0c;后接函數名和參數列表。 def greet(name):"""打印問候語&#xff08;文檔字符串&#xff09;"""print(f"Hello, {name}!") 調用&#xff1a…

關于Flutter中兩種Widget的生命周期詳解

目錄 一、StatelessWidget 生命周期 二、StatefulWidget 生命周期 1. 創建階段 2. State初始化階段 3. 構建階段 4. 更新階段 5. 銷毀階段 三、核心對比與常見陷阱 四、面試回答技巧 以下是Flutter中兩種核心Widget(StatelessWidget和StatefulWidget)生命周…

Linux 》》Ubuntu 18 LTS 之后的版本 修改IP地址 主機名

進入目錄 /etc/netplan 修改 50-cloud-init.yaml 》保存文件后&#xff0c;執行以下命令應用更改&#xff1a; sudo netplan apply 》》 DHCP模式 修改主機名 hostnamectl set-hostname xxxx 修改cloud.cfg 防止重啟主機名還原 但測試下來 不修改&#xff0c; 重啟 也不會還…

C++基礎 [三] - 面向對象三

初始化列表 首先&#xff0c;初始化列表是我們的祖師爺本賈尼博士為了解決在某些成員變量在定義時必須初始化的情況。這個初始化列表其實發生在構造函數之前&#xff0c;也就是實例化整個對象時先對所有的成員都進行了初始化 初始化的概念區分 在之前的博客學習中&#xff…

55年免費用!RevoUninstaller Pro專業版限時領取

今天&#xff0c;我要給大家介紹一款超給力的卸載工具——RevoUninstaller Pro。這是一款由保加利亞團隊精心打造的專業級卸載軟件&#xff0c;堪稱軟件卸載界的“神器”。 RevoUninstaller分為免費版和專業版。專業版功能更為強大&#xff0c;但通常需要付費才能解鎖全部功能。…

目前人工智能的發展,判斷10年、20年后的人工智能發展的主要方向,或者帶動的主要產業

根據2025年的最新行業研究和技術演進趨勢&#xff0c;結合歷史發展軌跡&#xff0c;未來10-20年人工智能發展的主要方向及帶動的產業將呈現以下六大核心趨勢&#xff1a; 一、算力革命與底層架構優化 核心地位&#xff1a;算力將成為類似“新能源電池”的基礎設施&#xff0c;…

【機器人】復現 ASGrasp 通用透明物體重建、6-DoF抓取預測

在機器人抓取領域&#xff0c;透明和鏡面物體的抓取一直是個難題。 ASGrasp核心是兩層學習型立體網絡&#xff0c;能夠同時恢復透明和鏡面物體的可見部分和不可見部分的深度信息。 然后融合兩層深度信息&#xff0c;進行重建物體&#xff0c;得到點云信息作為GSNet&#xff0…

2. qt寫帶有槽的登錄界面(c++)

我們在1.Qt寫簡單的登錄界面(c)_c qt 設計一個簡單界面-CSDN博客中寫了個簡單的登錄界面&#xff0c;但沒有槽&#xff0c;在這里寫一個帶有槽的界面。 1.代碼 代碼目錄如下&#xff1a; main.cpp的代碼如下&#xff1a; #include "MainWindow.h" #include <Qt…

windows安裝兩個或多個JDK,并實現自由切換

我用兩個JDK來做演示&#xff0c;分別是JDK8和JDK17(本人已安裝JDK8&#xff0c;所以這里只演示JDK17的安裝)。 1、下載JDK17安裝 Java Downloads | Oracle 2、安裝JDK17,這里忽略。直接雙擊軟件&#xff0c;點擊下一步就可以。 3、配置環境變量 在系統變量中新建一個CLASSP…

【2025最新】深度學習框架PyTorch——從入門到精通(1)下載與安裝

又名&#xff1a;蕪湖起飛俠的PyTorch學習記錄——從起飛到墜毀 簡介安裝內容總覽安裝AnacondaAnaconda簡介Anaconda下載配置環境變量驗證其他配置安裝matplotlib 安裝 CUDA安裝之前安裝cuDNN 安裝torchCPU 版本安裝GPU 版本安裝通過pip安裝&#xff08;不推薦&#xff09;通過…

C++數據結構1——棧結構詳解

一、棧的基本概念與特性 1. 棧的定義與特點 棧&#xff08;Stack&#xff09;是一種遵循后進先出&#xff08;LIFO, Last In First Out&#xff09;原則的線性數據結構&#xff0c;其核心特征包括&#xff1a; 單端操作&#xff1a;所有操作僅通過棧頂進行 動態存儲&#xf…

【Python 數據結構 15.哈希表】

目錄 一、哈希表的基本概念 1.哈希表的概念 2.鍵值對的概念 3.哈希函數的概念 4.哈希沖突的概念 5.常用的哈希函數 Ⅰ、直接定址法 Ⅱ、平方取中法 Ⅲ、折疊法 Ⅳ、除留余數法 Ⅴ、位與法 6.哈希沖突的解決方案 Ⅰ、開放定址法 Ⅱ、鏈地址法 7.哈希表的初始化 8.哈希表的元素插…

歷年云南大學計算機復試上機真題

歷年云南大學計算機復試機試真題 在線評測&#xff1a;傳送門&#xff1a;pgcode.cn 喝飲料 題目描述 商店里有 n 中飲料&#xff0c;第 i 種飲料有 mi 毫升&#xff0c;價格為 wi。 小明現在手里有 x 元&#xff0c;他想吃盡量多的飲料&#xff0c;于是向你尋求幫助&#x…

[文獻閱讀] 可變形卷積DCN - Deformable Convolutional Networks

**文獻信息&#xff1a;**Deformable Convolutional Networks arxiv.org/abs/1703.06211 發表于ICCV 2017&#xff0c;提出了可變形卷積DCN&#xff08;Deformable ConvNets&#xff09; 摘要 卷積神經網絡&#xff08;CNN&#xff09;由于其構建模塊固定的幾何結構天然地局限…

德語A1學習

Hast du morgen Zeit? Wann spielen wir? Vocabulary etwas/jemanden brauchen braucht, brauchte, hat gebraucht to need something/somebody Das geht. That works./Thats OK. den ganzen Tag the entire day dieser, diese, dieses this erst just; only G…

路局的上道檢修過程中,利用AI視覺技術對軌道兩旁設備設施進行檢修

在鐵路局的上道檢修過程中,利用AI視覺技術對軌道兩旁設備設施(如信號設備、電纜、接觸網、通信設備等)以及鐵路上方的電線(如接觸網、電力線)進行異常檢測,可以顯著提高檢修效率、降低人工成本并增強安全性。以下是具體的應用方案和技術路徑: 1. 應用場景 1.1 軌道兩旁…

函數指針/逗號表達式/不用if語句完成的字母輸出題

1.函數指針用的不是那么頻繁的一個操作&#xff1a; 下面是代碼演示&#xff1a; 在這個int (*jump)(int);中 jump是這個指針變量名稱&#xff0c;第一個int是指針類型&#xff0c;第二個int是指的這個指針所指的函數參數是int類型的。 #include <stdio.h>// 定義一個…