MyBatis SqlSessionFactory 是如何创建的?

embedded/2025/3/16 12:01:15/

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) 方法,传入配置文件的 InputStreambuild() 方法会解析 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): 调用 SqlSessionFactoryBuilderbuild(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();
    
    • 调用 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 实例:

    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 的构造器。
    • 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.ppmy.cn/embedded/173056.html

相关文章

DeepSeek-R1思路训练多模态大模型-Vision-R1开源及实现方法思路

刚开始琢磨使用DeepSeek-R1风格训练多模态R1模型&#xff0c;就看到这个工作&#xff0c;本文一起看看&#xff0c;供参考。 先提出问题&#xff0c;仅靠 RL 是否足以激励 MLLM 的推理能力&#xff1f; 结论&#xff1a;不能&#xff0c;因为如果 RL 能有效激励推理能力&#…

基于MATLAB的冰块变化仿真

如图1所示&#xff0c;边长为5cm的冰块&#xff0c;初始温度为-2℃&#xff0c;放在25℃的环境中自然冷却&#xff0c;对流换热系数为10W/mK&#xff0c;本文将通过matlab编程求解冰块融化的过程&#xff0c;计算其温度场。 图1 案例示意图 02 温度场计算 本文通过matlab分别…

RAG技术深度解析:从原理到企业级应用实战

一、RAG技术架构的核心价值 1.1 大模型时代的认知瓶颈 当前主流大语言模型(LLM)存在两大核心缺陷: 静态知识固化:GPT-4等模型的训练数据截止于2023年9月,无法实时更新行业动态领域专业知识缺失:在医疗、法律等高精度场景中,模型幻觉率高达12%-35%RAG(检索增强生成)通…

C++和C的区别

C和C语言虽然共享相似的语法&#xff0c;但在设计理念和功能特性上有显著区别。以下是两者的主要差异&#xff1a; 1. 编程范式 C&#xff1a;纯过程式编程&#xff0c;强调函数和步骤。C&#xff1a;支持多范式&#xff0c;包括面向对象编程&#xff08;类、继承、多态&…

linux Swap 分区

Swap 分区在 Linux 系统中的作用 Swap 分区&#xff08;交换分区&#xff09;相当于虚拟内存&#xff0c;在物理内存&#xff08;RAM&#xff09;不够用时&#xff0c;系统会将一部分磁盘空间作为虚拟内存使用。主要作用如下&#xff1a; 缓解内存不足&#xff1a;当物理内存…

内网渗透之内网基础知识(一)

工作组 工作组:工作组是局域网中的一个概念&#xff0c;他是长久的资源管理模式。默认情况下使 用工作组方式进行资源管理&#xff0c;将不同的 computer 按照不同的要求分类到不同的组 域:用来描述一种架构&#xff0c;和“工作组”相对应&#xff0c;由工作组升级而来的高级…

Winfrom基础知识41-60

41. 如何实现自定义控件的复杂绘制&#xff1f; 答案&#xff1a; 继承 Control 类并重写 OnPaint 方法&#xff0c;使用 Graphics 对象进行复杂绘制。 示例&#xff1a; public class CustomGraph : Control {protected override void OnPaint(PaintEventArgs e){base.OnPa…

TCP/IP原理详细解析

前言 TCP/IP是一种面向连接&#xff0c;可靠的传输&#xff0c;传输数据大小无限制的。通常情况下&#xff0c;系统与系统之间的http连接需要三次握手和四次挥手&#xff0c;这个执行过程会产生等待时间。这方面在日常开发时需要注意一下。 TCP/IP 是互联网的核心协议族&…