当前位置: 首页 > news >正文

【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.");}

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

相关文章:

【MyBatis源码】SqlSessionFactoryBuilder源码分析

文章目录 概述类结构从 InputStream 创建 SqlSessionFactoryXMLConfigBuilder构建ConfigurationXMLConfigBuilder初始化方法parse()方法parseConfiguration属性&#xff08;properties&#xff09; 概述 SqlSessionFactory 是 MyBatis 的核心接口之一&#xff0c;提供创建 Sql…...

Percona XtraBackup数据备份方案

一、简介 官方文档:https://docs.percona.com/percona-xtrabackup/innovation-release/index.html Percona XtraBackup 是一款适用于基于 MySQL 的服务器的开源热备份实用程序,可让您的数据库在计划的维护时段内保持完全可用。无论是 24x7 高负载服务器还是低交易量服务器,…...

聚“芯”而行,华普微亮相第五届Silicon Labs Works With大会

2024年10月24日&#xff0c;由致力于以安全、智能无线连接技术建立更互联世界的全球领导厂商Silicon Labs主办的第五届Works With开发者大会在上海雅乐居万豪侯爵酒店成功举办。 作为全球性的物联网年度“盛宴”&#xff0c;本届大会群英荟萃&#xff0c;不仅有着来自生态大厂的…...

Java 用户随机选择导入ZIP文件,解压内部word模板并入库,Windows/可视化Linux系统某麒麟国防系统...均可适配

1.效果 压缩包内部文件 2.依赖 <!--支持Zip--><dependency><groupId>net.lingala.zip4j</groupId><artifactId>zip4j</artifactId><version>2.11.5</version></dependency>总之是要File类变MultipartFile类型的 好像是…...

【C++】C++17结构化绑定、std::optional、std::variant、std::any

二十二、C17中的结构化绑定、std::optional、std::variant、std::any 本部分是一个小系列&#xff0c;介绍C17中新引入的、用来解决各种不同返回情况的、标准库新组件。 1、C的结构化绑定 结构化绑定structured bindings是C17中引入的一项特性&#xff0c;它允许开发者方便地…...

C#的起源。J++语言的由来?J#和J++傻傻分不清?

C#的起源 C#读音是C Sharp, 它是微软为了对抗Java而生&#xff0c;最早是J&#xff0c;效率比Java还好&#xff0c;后来被Sun公司起诉J破坏了平台无关性&#xff0c;微软重新开发C#. C#和Java一样都定位为中间件语言&#xff0c;用虚拟机执行编译的字节码以达到跨平台目的。从语…...

Flutter 在 对接 google play 时,利用 android studio 可视化生成 已签名的aab包

android studio 可视化生成 aab包 第一 &#xff1a; 先说注意事项 在Flutter项目里面&#xff0c;直接打开当前项目是不行的&#xff0c;不显示相应操作&#xff0c;需要在Android 目录打开&#xff0c;直白点就是直接打开项目里面的Android 目录 不然会出现的一些问题 第一…...

使用web.dev提供的工具实现浏览器消息推送服务

文章目录 前言实现工具和效果实现原理实现过程前端接收用户订阅请求将用户订阅信息更新到后端后端实现接收并保存订阅信息的接口后端实现消息推送的逻辑前言 对于电商独立站来说,新品上架或者促销活动上线及时通知到用户是很重要的,通知的渠道有很多,其中就包括浏览器消息推…...

计算机系统结构为什么用architecture 而不是structure?

architecture本意是建筑学、建筑艺术&#xff0c;其含义就是建筑的样子和背后的设计思想&#xff0c;用于计算机科学可以表达计算机的系统结构和后面的设计原理&#xff1a;它长什么样&#xff1f;它为什么长这样&#xff1f; 与architecture 对应的词是structure &#xff08…...

sqoop问题汇总记录

此篇博客仅记录在使用sqoop时遇到的各种问题。持续更新&#xff0c;有问题评论区一起探讨&#xff0c;写得有不足之处见谅。 Oracle_to_hive 1. main ERROR Could not register mbeans java.security.AccessControlException: access denied ("javax.management.MBeanTr…...

Git 创建新的分支但清空提交记录

有时候需要创建新的分支&#xff0c;但是原有分支的提交非常多&#xff0c;不好区分哪些是创建分支之后的提交。 那么就把原分支的提交全部去掉 要从 分支1 创建 分支2&#xff0c;并确保 分支2 不包含任何提交历史&#xff0c;同时文件与 分支1 的最后一次提交一致&#xff0…...

SQL PRIMARY KEY

SQL PRIMARY KEY 概述 在关系型数据库中&#xff0c;主键&#xff08;PRIMARY KEY&#xff09;是一个非常重要的概念。它是表中每一行数据的唯一标识符&#xff0c;用于保证数据的完整性和准确性。本文将详细介绍SQL中的主键&#xff0c;包括其定义、作用、如何创建和修改主键…...

软件测试学习笔记丨Flask操作数据库-对象与数据模型

本文转自测试人社区&#xff0c;原文链接&#xff1a;https://ceshiren.com/t/topic/23440 对象与数据模型 数据模型&#xff1a;是数据特征的抽象&#xff0c;抽象层次上描述了系统的静态特征、动态行为和约束条件&#xff0c;为数据库系统的信息表示与操作提供一个抽象的框架…...

IntelliJ IDEA使用 MybatisX-Generator 插件 自动生成Entity+Mapper+Mapper.xml等代码

一、Intellij安装MybatisX插件&#xff1a; 首先点击 Intellij->Preference->Plugins&#xff0c;然后搜索MybatisX&#xff0c;点击安装&#xff1a; 2 打开数据库 在IntelliJ IDEA 连接Mysql数据库&#xff0c;选择表&#xff0c;点击右键&#xff0c;选择 Mybatis…...

vue中如何为不同功能设置不同的默认打印设置(设置不同的打印机)

浏览器自带的window.print 功能较简单&#xff0c;这里使用LODOP露肚皮打印 以下是vue2示例&#xff1a; 从官网中下载Lodop和C-Lodop官网主站安装包并安装到本地电脑可以全局搜索电脑找到安装文件LodopFuncs.js&#xff0c;也可以直接复制我贴出来的文件 //用双端口加载主JS…...

经纬恒润INTEWORK-VBA新版本正式发布

在汽车电子研发领域&#xff0c;随着开发测试的深入&#xff0c;工程师们常常面临着一个共同的问题&#xff1a;如何高效地在多样化的开发测试场景中切换&#xff0c;并确保不同工具间的紧密协作。不同场景、不同工具的切换与使用给工程师带来高昂的学习成本和前后端信息传递的…...

金蝶云数据集成至MySQL的高效解决方案

金蝶云数据集成至MySQL的高效解决方案 金蝶云星空数据集成到MySQL的技术案例分享 在企业信息化过程中&#xff0c;数据的高效集成和管理是关键环节。本文将聚焦于一个具体的系统对接集成案例&#xff1a;金蝶云星空的数据如何通过轻易云数据集成平台无缝对接到MySQL数据库。本…...

Day02 C++ 环境设置

2024.11.1 C 环境设置 如果您想要设置 C 语言环境&#xff0c;需要确保电脑上有以下两款可用的软件&#xff0c;文本编辑器和 C 编译器。 一、文本编辑器 通过编辑器创建的文件通常称为源文件&#xff0c;源文件包含程序源代码。 C 程序的源文件通常使用扩展名 .cpp、.cp 或…...

AQS是什么

AQS&#xff1a;AbstructQueuedSynchronizer是java.util.concurrent.locks包中的一个类&#xff0c;是多线程同步器&#xff0c;J.U.C包中的多个组件的底层实现都使用到了它。如&#xff1a;Lock、CountDownLatch、Semaphore. 从本质上来说AQS实现了两种机制的锁&#xff0c;排…...

Spring IOC容器简介

Spring IoC&#xff08;Inversion of Control&#xff0c;控制反转&#xff09;容器是Spring框架的核心组件之一&#xff0c;负责管理应用程序中的对象及其依赖关系。IoC容器通过依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;实现对象的创建、配置和管理…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...

springboot 日志类切面,接口成功记录日志,失败不记录

springboot 日志类切面&#xff0c;接口成功记录日志&#xff0c;失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...

MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释

以Module Federation 插件详为例&#xff0c;Webpack.config.js它可能的配置和含义如下&#xff1a; 前言 Module Federation 的Webpack.config.js核心配置包括&#xff1a; name filename&#xff08;定义应用标识&#xff09; remotes&#xff08;引用远程模块&#xff0…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...