【源码】Mybatis源码
引言
MyBatis 作为 Java 开发中广泛使用的持久层框架,其高效且灵活的数据库操作能力备受开发者青睐。在日常开发中,我们熟练运用 MyBatis 的各种功能来实现数据持久化,但深入探究其源码,能让我们更透彻地理解它的工作原理,进而在实际应用中更好地优化和定制。本文将深入 MyBatis 的源码世界,剖析其核心流程与关键机制。
MyBatis 初始化流程源码剖析
配置文件加载
MyBatis 的初始化通常从加载配置文件开始。SqlSessionFactoryBuilder负责解析mybatis-config.xml配置文件。在解析过程中,它使用XPathParser对 XML 文件进行解析。例如,读取数据库连接信息时:
<dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/yourdb"/><property name="username" value="root"/><property name="password" value="password"/>
</dataSource>
XPathParser会定位到标签及其子标签,将这些配置信息提取出来,用于后续数据源的构建。通过一系列的解析逻辑,SqlSessionFactoryBuilder将配置文件中的各种设置转换为对应的 Java 对象,如Environment对象用于存储数据库环境信息,Configuration对象则是 MyBatis 的核心配置类,它包含了从数据源到映射器等一系列关键配置。
构建 SqlSessionFactory
在配置文件解析完成后,SqlSessionFactoryBuilder利用解析得到的Configuration对象构建SqlSessionFactory。DefaultSqlSessionFactory是SqlSessionFactory的默认实现类。在构建过程中,DefaultSqlSessionFactory会将Configuration对象中的各项配置信息整合起来,为后续创建SqlSession做准备。例如,它会根据Configuration中的事务管理器类型(如 JDBC 事务管理器或自定义事务管理器),初始化相应的事务管理机制。同时,它会将映射文件的信息加载并解析,构建出MappedStatement对象集合,这些MappedStatement对象对应着映射文件中的每一个 SQL 语句定义,包含了 SQL 语句本身、参数映射、结果映射等重要信息。
核心组件构建源码分析
Mapper 接口的动态代理生成
Mapper 接口在 MyBatis 中扮演着重要角色,它为开发者提供了一种面向接口编程的方式来操作数据库。MyBatis 通过动态代理机制为 Mapper 接口生成实现类。当 MyBatis 初始化时,会扫描所有的 Mapper 接口。对于每个 Mapper 接口,它使用MapperProxyFactory来创建代理对象。MapperProxyFactory实现了InvocationHandler接口,在invoke方法中,它根据调用的方法名,在Configuration对象中查找对应的MappedStatement。例如,当调用UserMapper.selectUserById方法时,MapperProxyFactory会根据UserMapper接口的命名空间以及方法名selectUserById,在Configuration的MappedStatement集合中找到对应的MappedStatement对象。然后,通过SqlSession来执行该MappedStatement对应的 SQL 语句,从而实现对数据库的查询操作。这种动态代理机制使得开发者无需编写 Mapper 接口的实现类,极大地简化了开发过程。
SqlSession 的创建与管理
SqlSession是 MyBatis 执行数据库操作的核心接口。DefaultSqlSession是SqlSession的默认实现类。当我们调用SqlSessionFactory.openSession()方法时,DefaultSqlSessionFactory会创建一个DefaultSqlSession实例。在创建过程中,它会根据Configuration中的配置信息,初始化事务管理和执行器(Executor)。执行器负责实际执行 SQL 语句,MyBatis 提供了SimpleExecutor、ReuseExecutor和BatchExecutor等多种执行器类型。例如,SimpleExecutor每次执行 SQL 语句时都会创建一个新的Statement对象,而ReuseExecutor则会复用已有的Statement对象,提高了执行效率。DefaultSqlSession通过持有执行器对象,在调用selectOne、selectList等方法时,将请求委托给执行器来执行 SQL 语句,并处理结果集的映射和返回。同时,DefaultSqlSession还负责管理事务,在事务开始、提交和回滚时,协调执行器和事务管理器进行相应的操作。
SQL 执行过程源码深入
SQL 语句的解析与参数映射
当SqlSession执行 SQL 语句时,首先会对 SQL 语句进行解析和参数映射。以select语句为例,MappedStatement对象中存储了 SQL 语句以及参数映射信息。MyBatis 使用BoundSql对象来表示经过解析和参数映射后的 SQL 语句。在生成BoundSql对象时,会根据参数类型和parameterType配置,将 Java 对象中的参数值替换到 SQL 语句中的占位符(如 #{id})处。例如,如果参数是一个User对象,且 SQL 语句中有 #{username} 占位符,MyBatis 会通过反射获取User对象的username属性值,并将其替换到 SQL 语句中。在这个过程中,MyBatis 还会处理一些复杂的参数映射情况,如集合参数、对象参数等,确保 SQL 语句能够正确地使用传入的参数。
结果集映射与返回
执行 SQL 语句后,MyBatis 需要将数据库返回的结果集映射到 Java 对象中。这一过程依赖于resultMap配置。ResultMap对象定义了数据库列与 Java 对象属性之间的映射关系。在解析结果集时,MyBatis 会根据ResultMap的配置,通过反射创建目标 Java 对象,并将结果集中的列值赋给对象的相应属性。例如,对于一个包含id、username等列的结果集,ResultMap中配置了id映射到 Java 对象的id属性,username映射到username属性,MyBatis 会逐行读取结果集,创建 Java 对象并填充属性值。对于复杂的对象关系,如一对一、一对多关系,ResultMap通过association和collection标签来处理。association用于处理一对一关系,collection用于处理一对多关系,确保复杂对象的映射能够准确无误地完成,最终将映射好的 Java 对象返回给调用者。
相关文章:
【源码】Mybatis源码
引言 MyBatis 作为 Java 开发中广泛使用的持久层框架,其高效且灵活的数据库操作能力备受开发者青睐。在日常开发中,我们熟练运用 MyBatis 的各种功能来实现数据持久化,但深入探究其源码,能让我们更透彻地理解它的工作原理&#…...
解决2080Ti使用节点ComfyUI-PuLID-Flux-Enhanced中遇到的问题
使用蓝大的工作流《一键同时换头、换脸、发型、发色之双pulid技巧》 刚开始遇到的是不支持bf16的错误 根据《bf16 is only supported on A100 GPUs #33》中提到,修改pulidflux.py中的dtype 为 dtype torch.float16 后,出现新的错误,这个…...
LabVIEW驱动开发的解决思路
在科研项目中,常面临将其他语言开发的定制采集设备驱动转换为 LabVIEW 适用形式的难题。特别是当原驱动支持匮乏、开发人员技术支持不足时,如何抉择解决路径成为关键。以下提供具体解决思路,助力高效解决问题。 一、评估现有驱动死磕的可…...
[英语] abominable、detestable、despicable、odious、contemptible的区别
关于 abominable 与其他近义词的辨析 abominable 的核心含义是“因极端恶劣或违背道德而令人憎恶”,其情感强度较高,常带有道德批判意味。以下是其与常见近义词的区别及典型用法: 1. abominable vs. detestable abominable:强调…...
七、Qt框架编写的多线程应用程序
一、大纲 学习内容:使用两个线程,分别点击两个按钮,触发两个不同的效果 所需控件:两个button、三个label 涉及知识点:多线程、Qt的connect机制、定时器、互斥锁 需求: 1,多线程定时计数&#x…...
MATLAB求和∑怎么用?
MATLAB求和∑怎么用? 一:题目:求下列方程的和 二、代码如下 1.syms函数 (方法一) 代码如下(示例): 1. syms x 2. symsum((x.^22*x).^3,1,100) 3. 2.直接用循环 (方法二) 代码如下&am…...
项目二 使用miniedit创建拓扑
一、项目需求分析: 1. 在ubuntu的桌面环境中运行Mininet的图形化界面2. Mininet图形化界面中搭建拓扑并设置相关的设备和链路属性3. Floodlight中查看拓扑4. 完成Mininet的测试 二、项目实施步骤 1. 运行Mininet图形化界面 在“~/mininet/examples”目录下有一m…...
Docker 镜像 的常用命令介绍
拉取镜像 $ docker pull imageName[:tag][:tag] tag 不写时,拉取的 是 latest 的镜像查看镜像 查看所有本地镜像 docker images or docker images -a查看完整的镜像的数字签名 docker images --digests查看完整的镜像ID docker images --no-trunc只查看所有的…...
0x02.Redis 集群的实现原理是什么?
回答重点 Redis 集群(Redis cluster)是通过多个 Redis 实例组成的,每个主节点实例负责存储部分的数据,并且可以有一个或多个从节点作为备份。 具体是采用哈希槽(Hash Slot)机制来分配数据,将整…...
浏览器多开
使用浏览器的用户功能,创建多个用户即可完成浏览器多开的需求,插件等相对独立 需要命名 然后就可以通过多个用户切换来实现多开了,不同任务选择不同用户...
Python中NumPy的逻辑和比较
在数据科学和科学计算领域,NumPy是一个不可或缺的Python库。它提供了高效的多维数组对象以及丰富的数组操作函数,其中逻辑和比较操作是NumPy的核心功能之一。通过灵活运用这些操作,我们可以轻松实现数据筛选、条件判断和复杂的数据处理任务。…...
20250412_代码笔记_CVRProblemDef
文章目录 前言一、get_random_problems 函数分析二、augment_xy_data_by_8_fold 函数分析代码 前言 该笔记分析代码的功能是生成随机VRP问题的数据,包含仓库坐标、节点坐标和节点需求。 对该代码进行改进 20250412-代码改进-拟蒙特卡洛 一、get_random_problems 函…...
机器学习(3)——决策树
文章目录 1. 决策树基本原理1.1. 什么是决策树?1.2. 决策树的基本构成:1.3. 核心思想 2. 决策树的构建过程2.1. 特征选择2.1.1. 信息增益(ID3)2.1.2. 基尼不纯度(CART)2.1.3. 均方误差(MSE&…...
Redis常用数据结构和应用场景
一、前言 Redis提供了多种数据结构,每种结构对应不同的应用场景。本文对部分常用的核心数据结构和典型使用场景作出介绍。 二、String(字符串) 特点:二进制安全,可存储文本、数字、序列化对象等。场景: 缓…...
【转载翻译】使用Open3D和Python进行点云处理
转自个人博客:【转载翻译】使用Open3D和Python进行点云处理 转载自:Point Cloud Processing with Open3D and Python 本文由 Carlos Melo 发布于2024年2月12日 本文很适合初学者对三维处理、点云处理以及Open3D库进行初步了解 另外,本文是基于…...
用户登录不上linux服务器
一般出现这种问题,重新用root用户修改lsy用户的密码即可登录,但是当修改了还是登录不了的时候,去修改一个文件用root才能修改, 然后在最后添加上改用户的名字,例如 原本是只有user的,现在我加上了lsy了&a…...
SQL 全文检索原理
全文检索(Full-Text Search)是SQL中用于高效搜索文本数据的技术,与传统的LIKE操作或简单字符串比较相比,它能提供更强大、更灵活的文本搜索能力。 基本概念 全文检索的核心思想是将文本内容分解为可索引的单元(通常是词或词组),然后建立倒排…...
dcsdsds
我将为您在页面顶部添加欢迎内容,同时保持整体风格的一致性。以下是修改后的代码,主要修改了模板部分和对应的样式: vue 复制 <template><div class"main-wrapper"><!-- 新增欢迎部分 --><div class"…...
FISCO BCOS区块链Postman接口测试:高级应用与实战技巧 [特殊字符]
引言:为什么Postman是FISCO BCOS测试的利器? 在区块链开发领域,接口测试是确保系统稳定性和安全性的关键环节。作为国产领先的联盟链平台,FISCO BCOS在金融、政务、供应链等多个领域得到广泛应用。而Postman作为一款功能强大的API测试工具,凭借其直观的图形界面和丰富的测…...
KWDB创作者计划—KWDB场景化创新实践:多模态数据融合与边缘智能的突破性应用
引言:AIoT时代的数据库范式重构 在工业物联网设备数量突破千亿、边缘计算节点覆盖率达75%的2025年,传统数据库面临多模态数据处理效率低下、边缘端算力利用率不足、跨域数据协同困难等核心挑战。KWDB(KaiwuDB Community Edition)通…...
风暴之眼:在AI重构的数字世界重绘职业坐标系
硅谷的某个深夜,GitHub Copilot在程序员的注视下自动生成出完美代码,这个场景正在全球数百万开发者的屏幕上同步上演。当AI生成的代码通过图灵测试,当机器学习模型开始理解业务需求,一个根本性命题浮出水面:在人类亲手…...
主机协议端口安全
FTP RDP SSH Rsync 渗透基础 | 黑客常用端口利用总结 - ZM思 - 博客园 (cnblogs.com)...
matplotlib数据展示
目录 一、绘制直方图 1、简单直方图 2、绘制横向直方图 3、绘制堆叠直方图 4、对比直方图 二、折线图与散点图 三、绘制饼图 四、雷达图 1、简单雷达图 2、多层雷达图 五、总和 在前面的学习中,我们能够使用一些库进行数据的整合,收集&#x…...
MySQL 面经
1、什么是 MySQL? MySQL 是一个开源的关系型数据库,现在隶属于 Oracle 公司。是我们国内使用频率最高的一种数据库,我本地安装的是比较新的 8.0 版本。 1.1 怎么删除/创建一张表? 可以使用 DROP TABLE 来删除表,使用…...
vLLM实战:多机多卡大模型分布式推理部署全流程指南
1. 环境准备与基础配置 1.1 系统要求 依赖组件: # 基础工具安装 sudo apt-get install -y lsof git-lfs nvidia-cuda-toolkit1.2 虚拟环境配置 使用conda创建隔离环境,避免依赖冲突: conda create -n vllm python3.10 -y conda activate…...
贪心算法 day08(加油站+单调递增的数字+坏了的计算机)
目录 1.加油站 2.单调递增的数字 3.坏了的计算器 1.加油站 链接:. - 力扣(LeetCode) 思路: gas[index] - cost[index],ret 表示的是在i位置开始循环时剩余的油量 a到达的最大路径假设是f那么我们可以得出 a b …...
String类基本使用
文章目录 1. String类的理解和创建对象2. 创建String对象的两种方式3. 两种创建String对象的区别4. 测试5. 字符串的特性6. String 类的常见方法 1. String类的理解和创建对象 String 对象用于保存字符串,也就是一组字符序列字符串常量对象是用双引号括起的字符序列…...
华为机试—火车进站
题目 火车站一共有 n 辆火车需要入站,每辆火车有一个编号,编号为 1 到 n。 同时,也有火车需要出站,由于火车站进出共享一个轨道,所以后入站的火车需要先出站。换句话说,对于某一辆火车,只有在它…...
Python数组(array)学习之旅:数据结构的奇妙冒险
Python数组学习之旅:数据结构的奇妙冒险 第一天:初识数组的惊喜 阳光透过窗帘缝隙洒进李明的房间,照亮了他桌上摊开的笔记本和笔记本电脑。作为一名刚刚转行的金融分析师,李明已经坚持学习Python编程一个月了。他的眼睛因为昨晚熬夜编程而微微发红,但脸上却挂着期待的微…...
spark-core编程2
Key-Value类型: foldByKey 当分区内计算规则和分区间计算规则相同时,aggregateByKey 就可以简化为 foldByKey combineByKey 最通用的对 key-value 型 rdd 进行聚集操作的聚集函数(aggregation function)。类似于aggregate()&…...
