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 配置文件构建 (最常用):
java">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 代码配置):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
对象:java">XMLConfigBuilder parser = new XMLConfigBuilder(inputStream);
XMLConfigBuilder
是 MyBatis 提供的 XML 配置解析器,专门用于解析 MyBatis 的 XML 配置文件。- 构造
XMLConfigBuilder
时,需要传入配置文件的InputStream
。
-
3.2. 解析 XML 配置文件并构建
Configuration
对象:java">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
实例:java">return build(configuration);
XMLConfigBuilder.parse()
方法最终会返回构建好的Configuration
对象。SqlSessionFactoryBuilder.build(InputStream inputStream)
方法内部会再次调用build(configuration)
方法,将解析得到的Configuration
对象传递给它。SqlSessionFactoryBuilder.build(Configuration config)
方法会真正创建DefaultSqlSessionFactory
实例,并将Configuration
对象作为构造参数传入。
-
3.4. 返回
SqlSessionFactory
实例:java">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
实例。