【MyBatis源码】SqlSessionFactoryBuilder源码分析

文章目录

    • 概述
    • 类结构
    • 从 InputStream 创建 SqlSessionFactory
    • XMLConfigBuilder构建Configuration
      • XMLConfigBuilder初始化方法
        • parse()方法
        • parseConfiguration
        • 属性(properties)

概述

SqlSessionFactory 是 MyBatis 的核心接口之一,提供创建 SqlSession 的方法。SqlSession 则是与数据库交互的主要接口,负责执行 SQL 命令和映射结果。SqlSessionFactoryBuilder 类的作用就是从 XML 配置文件或者其他配置源中加载配置信息,构建出 SqlSessionFactory 实例。

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resource);

类结构

在这里插入图片描述
SqlSessionFactoryBuilder 的基本结构如上,可以看出该类主要提供的就是build方法,但是参数不同,主要有3个不同参数类型的构建。
build(Reader reader):解析配置文件
build(InputStream inputStream):解析配置流
build(Configuration config):从 Configuration 对象构建 SqlSessionFactory

从 InputStream 创建 SqlSessionFactory

接下来我们将深入解析 SqlSessionFactoryBuilder 中的 build(InputStream inputStream) 方法的实现及其背后的细节。

  public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {try {// XMLConfigBuilder用来解析XML配置文件// 使用构建者模式// parser.parse()使用XPATH解析XML对象,将配置文件转换为Configuration对象XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);// new DefaultSqlSessionFactory,该对象持有Configuration对象return build(parser.parse());} catch (Exception e) {throw ExceptionFactory.wrapException("Error building SqlSession.", e);} finally {ErrorContext.instance().reset();try {inputStream.close();} catch (IOException e) {// Intentionally ignore. Prefer previous error.}}}

【方法参数说明】
• InputStream inputStream: 用于读取 XML 配置文件的输入流。这个流包含了 MyBatis 的配置信息,通常来自于 mybatis-config.xml 文件。
• String environment: 指定当前使用的环境。MyBatis 支持多种环境配置,例如开发、测试和生产。这个参数用于从配置中选择合适的数据库连接设置。具体使用那个由配置决定。
在这里插入图片描述
• Properties properties: 用于传递额外的配置信息。可以通过 Properties 对象向配置文件中添加一些动态的参数,便于灵活配置。

XMLConfigBuilder构建Configuration

MyBatis通过XMLConfigBuilder类完成Configuration对象的构建工作。下面是通过XMLConfigBuilder类创建Configuration的案例代码:

  /*** 测试XMLConfigBuilder类完成Configuration对象的构建*/@Testpublic void test5() throws Exception {InputStream resource = Resources.getResourceAsStream(MybatisTest.class.getClassLoader(), "mybatis-config.xml");XMLConfigBuilder xmlConfigBuilder = new XMLConfigBuilder(resource);Configuration parse = xmlConfigBuilder.parse();System.out.println(parse);}

在这里插入图片描述

XMLConfigBuilder初始化方法

  public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {// XPathParser是基于java path解析器,用于解析Mybatis中的配置文件this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);}
  public XPathParser(InputStream inputStream, boolean validation, Properties variables, EntityResolver entityResolver) {commonConstructor(validation, variables, entityResolver);// 解析XML文档为Document对象this.document = createDocument(new InputSource(inputStream));}

继续回到上一层代码,看XMLConfigBuilder的this()。super(new Configuration());
调用父类构造函数:创建一个新的 Configuration 对象,并将其传递给父类构造函数,表明当前 XMLConfigBuilder 的实例将使用这个全局配置对象。
在这里插入图片描述
在这里插入图片描述
以上的全局变量可以在mybatis的官方文档找到解释说明
在这里插入图片描述
https://mybatis.org/mybatis-3/zh_CN/configuration.html

MyBatis 的 Configuration 类是全局配置文件的核心,负责存储和管理应用程序的各种配置信息
Configuration 构造函数的主要作用是初始化类型别名注册器、设置默认的事务工厂、数据源、缓存策略、日志实现和语言驱动,确保 MyBatis 配置的灵活性和易用性。

parse()方法

继续看XMLConfigBuilder类parse()方法的实现,代码如下:

public Configuration parse() {// 防止parse()方法被同一个实例多次调用if (parsed) {throw new BuilderException("Each XMLConfigBuilder can only be used once.");}parsed = true;// parser.evalNode("/configuration") 获取配置文件configuration节点XNode对象// parseConfiguration:解析配置文件各个节点parseConfiguration(parser.evalNode("/configuration"));return configuration;}
parseConfiguration

继续看parseConfiguration核心方法
在这里插入图片描述
在parseConfiguration()方法中,对于标签的子节点,都有一个单独的方法处理,例如使用propertiesElement()方法解析标签,使用pluginElement()方法解析标签。MyBatis主配置文件中所有标签的用途如下。

具体配置这里可以对着MyBatis 的配置文件官方文档进行参考
https://mybatis.org/mybatis-3/zh_CN/configuration.html

属性(properties)

这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。例如:

<properties resource="org/mybatis/example/config.properties"><property name="username" value="dev_user"/><property name="password" value="F2Fa3!33TYyg"/>
</properties>

设置好的属性可以在整个配置文件中用来替换需要动态配置的属性值。比如:

<dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/>
</dataSource>

这个例子中的 username 和 password 将会由 properties 元素中设置的相应值来替换。 driver 和 url 属性将会由 config.properties 文件中对应的值来替换。这样就为配置提供了诸多灵活选择。
也可以在 SqlSessionFactoryBuilder.build() 方法中传入属性值。例如:

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, props);// ... 或者 ...SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, props);

:用于配置MyBatis数据连接相关的环境及事务管理器信息。通过该标签可以配置多个环境信息,然后指定具体使用哪个。标签的配置信息如下:

<environments default="development"><environment id="development"><transactionManager type="JDBC"><property name="..." value="..."/></transactionManager><dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment>
</environments>
environmentsElement(root.evalNode("environments"));

在这里插入图片描述
【序号1】这里的isSpecifiedEnvironment主要是主要用于判断当前指定的环境是否与传入的环境 ID 匹配,如果配置了多个environment标签组,则选择与环境 ID 匹配的那个进行加载处理。这个方法主要在环境配置的上下文中使用,例如在解析 XML 配置文件时,需要确保当前配置与指定的环境匹配。这对于支持多环境配置(如开发、测试、生产等)非常重要。
【序号2】这段代码是 MyBatis 中用于处理事务工厂配置的一个方法,主要负责从 XML 配置中解析并创建 TransactionFactory 实例。
在这里插入图片描述
【序号3】dataSourceElement用于解析获取数据库连接相关的配置信息。

private DataSourceFactory dataSourceElement(XNode context) throws Exception {if (context != null) {String type = context.getStringAttribute("type");// 获取<dataSource>子节点的配置Properties props = context.getChildrenAsProperties();// 根据getStringAttribute("type");获取对应的实现DataSourceFactoryDataSourceFactory factory = (DataSourceFactory) resolveClass(type).getDeclaredConstructor().newInstance();// 映射转换数据源配置 driver;url;username;passwordfactory.setProperties(props);return factory;}throw new BuilderException("Environment declaration requires a DataSourceFactory.");}

在这里插入图片描述
更多使用参见官方文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/458242.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue通过JSON文件生成WPML文件源码

可以使用封装的json解析器进行JSON数据获取&#xff0c;读取点的经度、维度、高程等数据&#xff0c;再使用对应的WPML文件生成函数使用该源码下载WPML文件&#xff08;固定WPML生成&#xff1a;js模板式生成大疆上云wpml文件&#xff08;含详细注释&#xff0c;已封装成函数&a…

(7) cuda异常处理

文章目录 上节概要异常处理代码 上节概要 上一节 block_width 64的时候&#xff0c;64644096 > 1024&#xff08;一个block里面最多只能有1024个线程&#xff0c;所以这里计算会有问题&#xff09; 异常处理 __FILE__: 编译器内部定义的一个宏。表示的是当前文件的文件…

【C++单调栈 贡献法】907. 子数组的最小值之和|1975

本文涉及的基础知识点 C单调栈 LeetCode907. 子数组的最小值之和 给定一个整数数组 arr&#xff0c;找到 min(b) 的总和&#xff0c;其中 b 的范围为 arr 的每个&#xff08;连续&#xff09;子数组。 由于答案可能很大&#xff0c;因此 返回答案模 109 7 。 示例 1&#x…

项目:Boost 搜索引擎

项目&#xff1a;Boost 搜索引擎 1、项目背景 公司&#xff1a;百度、360、搜狗、谷歌 …站内搜索&#xff1a;搜索的数据更垂直&#xff08;相关&#xff09;&#xff0c;数据量小 2、整体框架 3、技术栈和项目环境 技术栈&#xff1a;C/C C11&#xff0c;STL&#xff0c;jso…

error Unexpected mutation of “xxxxx“ prop

错误是在进行 eslint 检查的时候触发的&#xff0c;这个错误的原因是我们在子组件中改变了父组件传递过来的 props 解决方法一&#xff1a; 不改变父组件传递过来的 props&#xff0c;如果需要改变父组件传递过来的值&#xff0c;可以使用 defineModel() 进行接收值&#xff…

【零售和消费品&软件包】快递包装类型检测系统源码&数据集全套:改进yolo11-HSPAN

改进yolo11-EfficientHead等200全套创新点大全&#xff1a;快递包装类型检测系统源码&#xff06;数据集全套 1.图片效果展示 项目来源 人工智能促进会 2024.10.24 注意&#xff1a;由于项目一直在更新迭代&#xff0c;上面“1.图片效果展示”和“2.视频效果展示”展示的系统…

STM32第15章 RCC-使用HSE/HSI配置时钟

时间:2024.10.21-10.23 参考资料: 《零死角玩转STM32》“RCC-使用HSE/HIS配置时钟”章节 TIPS: 从前面的历程中我们知道,程序在启动的时候会执行汇编文件,汇编文件里会调用System_Init(固件库编程的函数),它里面会把时钟初始化成72M,因此前面我们在用固件库写程序的…

MSR寄存器独有的还是共享的

英特尔白皮书Volume 4: Model-Specific Registers 这一章列出了不同英特尔处理器系列的 MSR&#xff08;模型特定寄存器&#xff09;。所有列出的 MSR 都可以使用 RDMSR 和 WRMSR 指令进行读取和写入。MSR 的作用域定义了访问相同 MSR 的处理器集合&#xff0c;具体如下&#x…

栈和队列(上)-栈

1. 栈的概念 引入: 我们平时拿羽毛球,是从盒子顶部的羽毛球开始拿的,而顶部的元素是我们最后放进去的. 栈: 一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后…

温泉押金原路退回系统, 押金+手牌+电子押金单——未来之窗行业应用跨平台架构

一、温泉手牌收押金必要性 1. 防止手牌丢失&#xff1a;手牌是顾客在温泉内存储个人物品和进出更衣室的重要凭证。收押金可以让顾客更加重视手牌&#xff0c;降低丢失的概率。比如说&#xff0c;有的顾客可能会因为粗心大意随手放置手牌&#xff0c;如果没有押金的约束&…

STM32之外部中断(实验对射式传感器计次实验)

外部中断配置 #include "stm32f10x.h" // Device headeruint16_t CountSensor_Count;void CountSensor_Init(void) {//RCC--> GPIO--> AFIO--> EXTI--> NVIC五步RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //开启GPIOB时…

图---java---黑马

图 概念 图是由顶点(vertex)和边(edge)组成的数据结构&#xff0c;例如 该图有四个顶点&#xff1a;A&#xff0c;B&#xff0c;C&#xff0c;D以及四条有向边&#xff0c;有向图中&#xff0c;边是单向的。 有向 vs 无向 如果是无向图&#xff0c;那么边是双向的&#x…

aarch64-opencv341交叉编译,并在arm上部署helloopencv

背景 当需要在jetson xavier nx或者rk 3562等平台上开发关于视觉检测的工程时&#xff0c;由于arm板子资源不足或者不能联网等原因&#xff0c;通常在虚拟机上利用交叉编译器编译得到可执行程序&#xff0c;然后部署到arm板上。 aarch64-opencv341交叉编译 ubuntu虚拟机中先…

【Linux】环境下升级redis

一、摘要 最近漏洞扫描服务器发现&#xff0c;Redis 缓冲区溢出漏洞(CVE-2024-31449)&#xff0c;解决办法redis更新到6.2.16、7.2.6或7.4.1及以上版本。 二、漏洞描述 漏洞描述&#xff1a;经过身份验证的用户可能会使用特制的 Lua 脚本来触发位库中的堆栈缓冲区溢出&#…

Kaggle比赛复盘

Kaggle - LLM Prompt Recovery 解决方案报告 比赛背景/目标 大型语言模型&#xff08;Large Language Models&#xff0c;LLMs&#xff09;通常被用于改写或对文本进行风格修改。本次Kaggle竞赛的目标是根据给定的改写文本&#xff0c;还原用于将原始文本转换为改写文本的LLM…

MetaArena推出《Final Glory》:引领Web3游戏技术新风向

随着区块链技术的日益成熟&#xff0c;Web3游戏成为了游戏产业探索的新方向&#xff0c;将去中心化经济与虚拟世界结合在一起&#xff0c;形成了一个全新的生态体系。然而&#xff0c;尽管Web3游戏展示了令人兴奋的可能性&#xff0c;但其背后的技术障碍依旧严峻&#xff0c;特…

Android Activity SingleTop启动模式使用场景

通知栏 当用户点击通知栏中的通知时,可以使用单顶启动模式来打开对应的活动,并确保只有一个实例存在。 简单集成极光推送 创建应用 获取appkey参数 切换到极光工作台 极光sdk集成 Project 根目录的主 gradle 配置 Module 的 gradle 配置 Jpush依赖配置 配置推送必须…

华为原生鸿蒙操作系统:我国移动操作系统的新篇章

华为原生鸿蒙操作系统&#xff1a;我国移动操作系统的新篇章 引言 在移动操作系统领域&#xff0c;苹果iOS和安卓系统一直占据主导地位。然而&#xff0c;随着华为原生鸿蒙操作系统的正式发布&#xff0c;这一格局正在发生深刻变化。作为继苹果iOS和安卓系统后的全球第三大移动…

Python酷库之旅-第三方库Pandas(170)

目录 一、用法精讲 781、pandas.arrays.IntervalArray.contains方法 781-1、语法 781-2、参数 781-3、功能 781-4、返回值 781-5、说明 781-6、用法 781-6-1、数据准备 781-6-2、代码示例 781-6-3、结果输出 782、pandas.arrays.IntervalArray.overlaps方法 782-1…