【MyBatis】源码学习 05 - 关于 xml 文件解析的分析
文章目录
- 前言
- 参考目录
- 学习笔记
- 1、章节目录概览
- 2、`14.3`:`SqlSourceBuilder` 类与 `StaticSqlSource` 类
- 3、`14.4.2`:`ResultMapResolver` 类
- 3.1、测试代码说明
- 3.2、结果集 `userMap` 解析流程
- 3.3、结果集 `getGirl` 解析流程
- 3.4、鉴别器 `discriminator` 解析流程
- 4、`14.6`:XML 文件解析
- 5、`14.6.2`:配置文件解析
- 6、`14.6.3`:数据库操作语句解析
- 7、`14.6.4`:Statement 解析
- 8、`14.7`:注解映射的解析
前言
本文内容对应的是书本第 14 章的内容,主要是关于 builder
包的学习,本章节的内容比较多,每一小节都有相应的例子进行说明,也附带了源码的注释说明,因此本文只是选择了本章节一部分的内容来进行 Debug 分析说明。
参考目录
- 《通用源码阅读指导书:MyBatis源码详解》
本文主要内容来自第14章 builder包
。 - 《通用源码阅读指导书——MyBatis源码详解》配套示例
书中涉及的 Demo 示例,本文示例在Demo13
的基础上进行了简单改造。
与上篇一样,需要说明的是,书中使用的框架版本和本文(本专栏)使用的版本不一样。
名称 | 书中版本 | 专栏版本 |
---|---|---|
MyBatis | 3.5.2 | 3.5.11+ |
Spring Boot | 2.X | 3.X |
JDK | 8 | 17+ |
随着版本的升级迭代,会有一些内容不尽相同,需要结合着进行学习。
学习笔记
1、章节目录概览
由于我在微信读书看书的时候,电子版对于书本章节里面的小节并没有进行详细的划分,有些小节的内容并没有在目录体现出来,对于想要快速查找资料不太方便,所以下面简单的做了整理,方便后面复习时进行对照查找。
(加粗的部分是下面会进行分析的内容)
- 14.1 建造者模式
- 14.2 建造者基类与工具类
- 14.3 SqlSourceBuilder类与StaticSqlSource类
- 14.4 CacheRefResolver类和ResultMapResolver类
- 14.4.1 CacheRefResolver类
- 14.4.2 ResultMapResolver类
- 14.5 ParameterExpression类
- 14.6 XML文件解析
- 14.6.1 XML文件的声明解析
- 14.6.2 配置文件解析
- 14.6.3 数据库操作语句解析
- 14.6.4 Statement解析
- 14.6.5 引用解析
- 14.7 注解映射的解析
- 14.7.1 注解映射的使用
- 14.7.2 注解映射解析的触发
- 14.7.3 直接注解映射的解析
- 14.7.4 间接注解映射的解析
2、14.3
:SqlSourceBuilder
类与 StaticSqlSource
类
SqlSourceBuilder 类能够将 DynamicSqlSource 和 RawSqlSource 中的“#{}”符号替换掉,从而将它们转化为 StaticSqlSource。
#{}
其实是 xml 文件中很重要的参数占位符,而 SqlSourceBuilder
的作用就是把占位符解析并转换成为 SQL,下面通过一个简单的示例来 Debug 看一下这个过程。
测试的SQL:
<select id="selectById" resultType="User">SELECT * FROM `user` WHERE id = #{id}</select>
SqlSourceBuilder#parse
GenericTokenParser#parse
解析完成后,返回 SqlSourceBuilder#parse
方法构建 StaticSqlSource
:
StaticSqlSource#StaticSqlSource
3、14.4.2
:ResultMapResolver
类
借助于 MapperBuilderAssistant 的 addResultMap 方法,ResultMapResolver 完成了ResultMap 的继承关系解析,最终给出一个解析完继承关系之后的ResultMap 对象。
3.1、测试代码说明
跟参考目录 Demo 中的 Demo13
类似,测试代码如下:
ResultMap 对象的解析由主节点到子节点依次进行,下面的分析也分成三个部分,分别是 userMap
,getGirl
以及 discriminator
。
3.2、结果集 userMap
解析流程
XMLMapperBuilder#resultMapElements
XMLMapperBuilder#resultMapElement
resultMap 继承关系的解析由 ResultMapResolver 类来完成。
ResultMapResolver#resolve
借助于 MapperBuilderAssistant 的 addResultMap 方法,ResultMapResolver 完成了ResultMap 的继承关系解析,最终给出一个解析完继承关系之后的ResultMap 对象。
MapperBuilderAssistant#addResultMap
3.3、结果集 getGirl
解析流程
XMLMapperBuilder#resultMapElements
XMLMapperBuilder#resultMapElement
ResultMapResolver#resolve
MapperBuilderAssistant#addResultMap
3.4、鉴别器 discriminator
解析流程
XMLMapperBuilder#resultMapElement
XMLMapperBuilder#processDiscriminatorElement
解析结果:
4、14.6
:XML 文件解析
解析的语句:
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5、14.6.2
:配置文件解析
先抛出结论:
XMLConfigBuilder在 MyBatis的配置解析中起到了引导的作用,正是从它的parse方法开始,引发了配置文件和映射文件的解析。
放到代码当中,实际上是创建 SqlSessionFactory
时,XMLConfigBuilder
对 XML 文件进行解析。
执行方法的调用链如下:
org.apache.ibatis.session.SqlSessionFactoryBuilder#build
org.apache.ibatis.builder.xml.XMLConfigBuilder#parse
org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration
org.apache.ibatis.builder.xml.XMLConfigBuilder#environmentsElement
XML 配置文件 mybatis-config.xml
XMLConfigBuilder#parseConfiguration
XMLConfigBuilder#environmentsElement
一共三部分:默认环境,事务管理器 TransactionFactory
,数据源 DataSourceFactory
。
参数 XNode context
:
默认环境
事务管理器 TransactionFactory
XMLConfigBuilder#transactionManagerElement
数据源 DataSourceFactory
XMLConfigBuilder#dataSourceElement
最终解析完成 XMLConfigBuilder#environmentsElement
:
6、14.6.3
:数据库操作语句解析
parse 方法为解析的入口方法,然后调用configurationElement 方法逐层完成解析。
和配置文件解析过程类似,执行方法的调用链如下:
org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration
org.apache.ibatis.builder.xml.XMLConfigBuilder#mapperElement
org.apache.ibatis.builder.xml.XMLMapperBuilder#parse
org.apache.ibatis.builder.xml.XMLMapperBuilder#configurationElement
由 configurationElement(parser.evalNode(“/mapper”))语句触发后,系统会依次解析映射文件的各个节点。
XMLMapperBuilder#parse
参数 XNode context
:
cacheRefElement
:缓存引用cacheElement
:缓存parameterMapElement
:参数映射resultMapElements
:结果映射sqlElement
:sqlbuildStatementFromContext
:从上下文构建语句
7、14.6.4
:Statement 解析
这里主要是承接上一小节对 buildStatementFromContext
方法进行了说明。
执行方法的调用链如下:
org.apache.ibatis.builder.xml.XMLMapperBuilder#buildStatementFromContext
org.apache.ibatis.builder.xml.XMLStatementBuilder#parseStatementNode
XMLStatementBuilder#parseStatementNode
MapperBuilderAssistant#addMappedStatement
解析完成的 statement
:
8、14.7
:注解映射的解析
这里主要是对于书中没有详细说明的 泛型桥接方法
进行简单的拓展。
关于这一方面我和 ChatGPT 来回讨论了几次然后有了以下说明:
还有一些补充说明作为辅助理解:
关于该方法的参数讨论:
(完)
相关文章:

【MyBatis】源码学习 05 - 关于 xml 文件解析的分析
文章目录前言参考目录学习笔记1、章节目录概览2、14.3:SqlSourceBuilder 类与 StaticSqlSource 类3、14.4.2:ResultMapResolver 类3.1、测试代码说明3.2、结果集 userMap 解析流程3.3、结果集 getGirl 解析流程3.4、鉴别器 discriminator 解析流程4、14.…...

代码随想录算法训练营第二天| 977. 有序数组的平方、209. 长度最小子数组、59.螺旋矩阵II
977 有序数组的平方题目链接:977 有序数组的平方介绍给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。思路看到题目的第一反应,首先负数的平方跟正数的平方是相同的&…...

Ethercat系列(10)用QT实现SOEM主站
首先将SOEM编译成静态Lib库可以参考前面的博文(83条消息) VS2017下编译SOEM(Simle Open EtherCAT Master)_soem vs_CoderIsArt的博客-CSDN博客make_libsoem_lib.bat "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build" x86用QT创建…...

论文投稿指南——中文核心期刊推荐(科学、科学研究)
【前言】 🚀 想发论文怎么办?手把手教你论文如何投稿!那么,首先要搞懂投稿目标——论文期刊 🎄 在期刊论文的分布中,存在一种普遍现象:即对于某一特定的学科或专业来说,少数期刊所含…...
jQuery属性操作prop()、attr()和data()
jQuery 提供了一些属性操作的方法,主要包括 prop()、attr() 和 data() 等。通过这些方法,能够实现不同的需求。下面我们分别进行详细讲解。 1.prop() 方法 prop0 方法用来设置或获取元素固有属性值。元素固有属性是指元素本身自带的属性,如 …...

git的使用
1.git的四个区域: 2.常规git命令 git status 查看working directory哪些文件被更改了git add .把更改add到staging area,缓存的地方。改一个地方可以就先暂存一下,最后确认是哪些改动后再一起commit,以免不必要的版本。 在暂存区域ÿ…...

webpack生产环境配置
3 webpack生产环境配置 由于笔记文档没有按照之前的md格式书写,所以排版上代码上存在问题😢😢😢😢 09 提取css成单独文件 使用下载插件 npm i mini-css-extract-plugin0.9.0 -D webpack配置此时a,b提取成单独文件,并且…...

linux下安装jenkins
1.初始化Jenkins安装环境 系统版本:Red Hat Enterprise Linux 8.7 将脚本文件jenkins_install_env.sh 、 jenkins_install.sh和apache-maven-3.6.2-bin.tar.gz、jdk-8u251-linux-x64.tar.gz都上传到/usr/local/src目录下执行jenkins_install_env.sh脚本初始化Jenki…...

IGKBoard(imx6ull)-I2C接口编程之SHT20温湿度采样
文章目录1- 使能开发板I2C通信接口2- SHT20硬件连接3- 编码实现SHT20温湿度采样思路(1)查看sht20从设备地址(i2cdetect)(2)获取数据大体流程【1】软复位【2】触发测量与通讯时序(3)返…...

MyBatis——配置文件完成增删改查
1.首先先创建一个新的表,使用下面的sql语句 -- 删除tb_brand表 drop table if exists tb_brand; -- 创建tb_brand表 create table tb_brand (-- id 主键id int primary key auto_increment,-- 品牌名称brand_name varchar(20),-- 企业名称company_name varchar(20…...
Python内置函数 — all,any
1、all 源码注释: def all(*args, **kwargs): # real signature unknown"""Return True if bool(x) is True for all values x in the iterable.If the iterable is empty, return True."""pass 语法格式: all(iterable)…...

Pycharm配置QGIS环境
版本信息:QGIS: 3.22.16Pycharm:2022.3.2 (Community Edition)在QGIS官网下载安装包,下载稳定版本即可。配置步骤:安装完成后,使用Pycharm新建工程Python编译器选择之前配置好的编译器环境选择左侧第一个Vi…...

【C++】stack 与 queue
stack 与 queuestackSTL 容器中 stack 的使用模拟实现 stackqueueSTL 容器中 queue 的使用模拟实现 queuestack 在数据结构中,我们了解到,stack 栈结构,是一种先进后出的结构,并且我们是使用顺序表来进行实现栈的操作的。 STL 容…...
ARC142E Pairing Wizards
ARC142E Pairing Wizards 题目大意 有nnn个法师,编号为111到nnn。法师iii有强度aia_iai,他计划打败强壮度为bib_ibi的怪物。 你可以执行以下操作任意次: 选中一个法师,将它的强壮度增加1 一对法师(i,j)(i,j)(i,j)称为好的…...
Spark开发实战-主播打赏排行榜统计
(一)需求分析 计算每个大区当天金币收入排名前N的主播 背景: 我们有一款直播APP,已经在很多国家上线并运营了一段时间,产品经理希望开发一个功能,计算前N主播排行榜,按天更新排名信息…...

python 如何存储数据 (python 的文件和异常)
文章目录存储数据1. 使用 json.dump() 和 json.load()json.dump()2. 保存和读取用户生成的数据存储数据 很多程序都要求用户输入某种信息,如让用户存储游戏首选项或提供要可视化的数据。不管专注的是什么,程序都把用户提供的信息存储在列表和字典等数据结…...

第三章-OpenCV基础-8-绘图函数
前置内容 这篇内容不是本书内容,但后续用的到,特做记录。 使用OpenCV中不可避免需要用到各种绘图功能,比如绘制人脸库、显示人脸识别信息,那就需要用到OpenCV的绘图函数,这些函数包括cv2.line(), cv2.circle(),cv2.rectangle()…...

逆约瑟夫问题
约瑟夫问题可以说十分经典,其没有公式解也是广为人知的~ 目录 前言 一、约瑟夫问题与逆约瑟夫问题 1.约瑟夫问题 2.逆约瑟夫问题 二、思考与尝试(显然有很多失败) 问题分析 尝试一:递归/递推的尝试 尝试二:条件…...
MySQL之三大日志(更新中)
MySQL之三大日志(更新中) MySQL日志记录着数据库运行过程中的各种信息,包括:错误日志、普通查询日志、慢查询日志、二进制日志、中继日志、事务日志等。 综合上一篇《MySQL之"幻读"问题》涉及到事务,本文主…...

如何使用EvilTree在文件中搜索正则或关键字匹配的内容
关于EvilTree EvilTree是一款功能强大的文件内容搜索工具,该工具基于经典的“tree”命令实现其功能,本质上来说它就是“tree”命令的一个独立Python 3重制版。但EvilTree还增加了在文件中搜索用户提供的关键字或正则表达式的额外功能,而且还…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...