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)
方法,傳入配置文件的InputStream
。build()
方法會解析 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)
: 調用SqlSessionFactoryBuilder
的build(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();
- 調用
XMLConfigBuilder
的parse()
方法,開始解析 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 接口生成代理對象。
- 對于 XML 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
的構造器。DefaultSqlSessionFactory
是SqlSessionFactory
接口的默認實現類,它內部持有Configuration
對象,并負責創建SqlSession
實例。SqlSessionFactoryBuilder.build()
方法最終會返回創建好的SqlSessionFactory
實例。
4. SqlSessionFactory
的生命周期:
SqlSessionFactory
一旦被創建,應該在應用的整個生命周期內都存在。 最佳實踐是在應用啟動時創建SqlSessionFactory
,并將其作為單例 (Singleton) 對象進行管理和使用。- 在 Spring 環境中,
SqlSessionFactory
通常由 Spring 容器管理,聲明為 Spring Bean,并由 Spring 負責其生命周期管理。
總結 SqlSessionFactory
創建的關鍵步驟:
- 加載 MyBatis 配置信息 (XML 配置文件或 Java 代碼配置)。
- 創建
SqlSessionFactoryBuilder
實例。 - 調用
SqlSessionFactoryBuilder.build()
方法,傳入配置信息 (例如InputStream
或Configuration
對象)。 SqlSessionFactoryBuilder.build()
內部:- 創建
XMLConfigBuilder
(如果使用 XML 配置)。 XMLConfigBuilder
解析 XML 配置文件,構建并填充Configuration
對象。SqlSessionFactoryBuilder
使用Configuration
對象創建DefaultSqlSessionFactory
實例。
- 創建
- 返回
SqlSessionFactory
實例。
SqlSessionFactory
的重要性:
SqlSession
工廠:SqlSessionFactory
是SqlSession
的工廠,負責創建SqlSession
實例。- 配置中心:
SqlSessionFactory
內部持有Configuration
對象,包含了 MyBatis 的所有配置信息 (數據源、事務管理器、Mapper 映射、全局設置等)。Configuration
對象是 MyBatis 配置信息的中心倉庫。 - 性能優化:
SqlSessionFactory
是重量級對象,創建過程相對耗時,但創建后可以重復使用,避免了每次數據庫操作都重新解析配置和創建工廠的開銷。 將其作為單例管理可以提高性能。 - 線程安全:
SqlSessionFactory
本身是線程安全的,可以被多個線程共享使用。 但SqlSession
實例不是線程安全的,每個線程應該擁有自己的SqlSession
實例。