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

【源码】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 开发中广泛使用的持久层框架&#xff0c;其高效且灵活的数据库操作能力备受开发者青睐。在日常开发中&#xff0c;我们熟练运用 MyBatis 的各种功能来实现数据持久化&#xff0c;但深入探究其源码&#xff0c;能让我们更透彻地理解它的工作原理&#…...

解决2080Ti使用节点ComfyUI-PuLID-Flux-Enhanced中遇到的问题

使用蓝大的工作流《一键同时换头、换脸、发型、发色之双pulid技巧》 刚开始遇到的是不支持bf16的错误 根据《bf16 is only supported on A100 GPUs #33》中提到&#xff0c;修改pulidflux.py中的dtype 为 dtype torch.float16 后&#xff0c;出现新的错误&#xff0c;这个…...

LabVIEW驱动开发的解决思路

在科研项目中&#xff0c;常面临将其他语言开发的定制采集设备驱动转换为 LabVIEW 适用形式的难题。特别是当原驱动支持匮乏、开发人员技术支持不足时&#xff0c;如何抉择解决路径成为关键。以下提供具体解决思路&#xff0c;助力高效解决问题。 ​ 一、评估现有驱动死磕的可…...

[英语] abominable、detestable、despicable、odious、contemptible的区别

关于 abominable 与其他近义词的辨析 abominable 的核心含义是“因极端恶劣或违背道德而令人憎恶”&#xff0c;其情感强度较高&#xff0c;常带有道德批判意味。以下是其与常见近义词的区别及典型用法&#xff1a; 1. abominable vs. detestable abominable&#xff1a;强调…...

七、Qt框架编写的多线程应用程序

一、大纲 学习内容&#xff1a;使用两个线程&#xff0c;分别点击两个按钮&#xff0c;触发两个不同的效果 所需控件&#xff1a;两个button、三个label 涉及知识点&#xff1a;多线程、Qt的connect机制、定时器、互斥锁 需求&#xff1a; 1&#xff0c;多线程定时计数&#x…...

MATLAB求和∑怎么用?

MATLAB求和∑怎么用&#xff1f; 一&#xff1a;题目&#xff1a;求下列方程的和 二、代码如下 1.syms函数 &#xff08;方法一) 代码如下&#xff08;示例&#xff09;&#xff1a; 1. syms x 2. symsum((x.^22*x).^3,1,100) 3. 2.直接用循环 (方法二) 代码如下&am…...

项目二 使用miniedit创建拓扑

一、项目需求分析&#xff1a; 1. 在ubuntu的桌面环境中运行Mininet的图形化界面2. Mininet图形化界面中搭建拓扑并设置相关的设备和链路属性3. Floodlight中查看拓扑4. 完成Mininet的测试 二、项目实施步骤 1. 运行Mininet图形化界面 在“~/mininet/examples”目录下有一m…...

Docker 镜像 的常用命令介绍

拉取镜像 $ docker pull imageName[:tag][:tag] tag 不写时&#xff0c;拉取的 是 latest 的镜像查看镜像 查看所有本地镜像 docker images or docker images -a查看完整的镜像的数字签名 docker images --digests查看完整的镜像ID docker images --no-trunc只查看所有的…...

0x02.Redis 集群的实现原理是什么?

回答重点 Redis 集群&#xff08;Redis cluster&#xff09;是通过多个 Redis 实例组成的&#xff0c;每个主节点实例负责存储部分的数据&#xff0c;并且可以有一个或多个从节点作为备份。 具体是采用哈希槽&#xff08;Hash Slot&#xff09;机制来分配数据&#xff0c;将整…...

浏览器多开

使用浏览器的用户功能&#xff0c;创建多个用户即可完成浏览器多开的需求&#xff0c;插件等相对独立 需要命名 然后就可以通过多个用户切换来实现多开了&#xff0c;不同任务选择不同用户...

Python中NumPy的逻辑和比较

在数据科学和科学计算领域&#xff0c;NumPy是一个不可或缺的Python库。它提供了高效的多维数组对象以及丰富的数组操作函数&#xff0c;其中逻辑和比较操作是NumPy的核心功能之一。通过灵活运用这些操作&#xff0c;我们可以轻松实现数据筛选、条件判断和复杂的数据处理任务。…...

20250412_代码笔记_CVRProblemDef

文章目录 前言一、get_random_problems 函数分析二、augment_xy_data_by_8_fold 函数分析代码 前言 该笔记分析代码的功能是生成随机VRP问题的数据&#xff0c;包含仓库坐标、节点坐标和节点需求。 对该代码进行改进 20250412-代码改进-拟蒙特卡洛 一、get_random_problems 函…...

机器学习(3)——决策树

文章目录 1. 决策树基本原理1.1. 什么是决策树&#xff1f;1.2. 决策树的基本构成&#xff1a;1.3. 核心思想 2. 决策树的构建过程2.1. 特征选择2.1.1. 信息增益&#xff08;ID3&#xff09;2.1.2. 基尼不纯度&#xff08;CART&#xff09;2.1.3. 均方误差&#xff08;MSE&…...

Redis常用数据结构和应用场景

一、前言 Redis提供了多种数据结构&#xff0c;每种结构对应不同的应用场景。本文对部分常用的核心数据结构和典型使用场景作出介绍。 二、String&#xff08;字符串&#xff09; 特点&#xff1a;二进制安全&#xff0c;可存储文本、数字、序列化对象等。场景&#xff1a; 缓…...

【转载翻译】使用Open3D和Python进行点云处理

转自个人博客&#xff1a;【转载翻译】使用Open3D和Python进行点云处理 转载自&#xff1a;Point Cloud Processing with Open3D and Python 本文由 Carlos Melo 发布于2024年2月12日 本文很适合初学者对三维处理、点云处理以及Open3D库进行初步了解 另外&#xff0c;本文是基于…...

用户登录不上linux服务器

一般出现这种问题&#xff0c;重新用root用户修改lsy用户的密码即可登录&#xff0c;但是当修改了还是登录不了的时候&#xff0c;去修改一个文件用root才能修改&#xff0c; 然后在最后添加上改用户的名字&#xff0c;例如 原本是只有user的&#xff0c;现在我加上了lsy了&a…...

SQL 全文检索原理

全文检索(Full-Text Search)是SQL中用于高效搜索文本数据的技术&#xff0c;与传统的LIKE操作或简单字符串比较相比&#xff0c;它能提供更强大、更灵活的文本搜索能力。 基本概念 全文检索的核心思想是将文本内容分解为可索引的单元(通常是词或词组)&#xff0c;然后建立倒排…...

dcsdsds

我将为您在页面顶部添加欢迎内容&#xff0c;同时保持整体风格的一致性。以下是修改后的代码&#xff0c;主要修改了模板部分和对应的样式&#xff1a; vue 复制 <template><div class"main-wrapper"><!-- 新增欢迎部分 --><div class"…...

FISCO BCOS区块链Postman接口测试:高级应用与实战技巧 [特殊字符]

引言:为什么Postman是FISCO BCOS测试的利器? 在区块链开发领域,接口测试是确保系统稳定性和安全性的关键环节。作为国产领先的联盟链平台,FISCO BCOS在金融、政务、供应链等多个领域得到广泛应用。而Postman作为一款功能强大的API测试工具,凭借其直观的图形界面和丰富的测…...

KWDB创作者计划—KWDB场景化创新实践:多模态数据融合与边缘智能的突破性应用

引言&#xff1a;AIoT时代的数据库范式重构 在工业物联网设备数量突破千亿、边缘计算节点覆盖率达75%的2025年&#xff0c;传统数据库面临多模态数据处理效率低下、边缘端算力利用率不足、跨域数据协同困难等核心挑战。KWDB&#xff08;KaiwuDB Community Edition&#xff09;通…...

风暴之眼:在AI重构的数字世界重绘职业坐标系

硅谷的某个深夜&#xff0c;GitHub Copilot在程序员的注视下自动生成出完美代码&#xff0c;这个场景正在全球数百万开发者的屏幕上同步上演。当AI生成的代码通过图灵测试&#xff0c;当机器学习模型开始理解业务需求&#xff0c;一个根本性命题浮出水面&#xff1a;在人类亲手…...

主机协议端口安全

FTP RDP SSH Rsync 渗透基础 | 黑客常用端口利用总结 - ZM思 - 博客园 (cnblogs.com)...

matplotlib数据展示

目录 一、绘制直方图 1、简单直方图 2、绘制横向直方图 3、绘制堆叠直方图 4、对比直方图 二、折线图与散点图 三、绘制饼图 四、雷达图 1、简单雷达图 2、多层雷达图 五、总和 在前面的学习中&#xff0c;我们能够使用一些库进行数据的整合&#xff0c;收集&#x…...

MySQL 面经

1、什么是 MySQL&#xff1f; MySQL 是一个开源的关系型数据库&#xff0c;现在隶属于 Oracle 公司。是我们国内使用频率最高的一种数据库&#xff0c;我本地安装的是比较新的 8.0 版本。 1.1 怎么删除/创建一张表&#xff1f; 可以使用 DROP TABLE 来删除表&#xff0c;使用…...

vLLM实战:多机多卡大模型分布式推理部署全流程指南

1. 环境准备与基础配置 1.1 系统要求 依赖组件&#xff1a; # 基础工具安装 sudo apt-get install -y lsof git-lfs nvidia-cuda-toolkit1.2 虚拟环境配置 使用conda创建隔离环境&#xff0c;避免依赖冲突&#xff1a; conda create -n vllm python3.10 -y conda activate…...

贪心算法 day08(加油站+单调递增的数字+坏了的计算机)

目录 1.加油站 2.单调递增的数字 3.坏了的计算器 1.加油站 链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; gas[index] - cost[index]&#xff0c;ret 表示的是在i位置开始循环时剩余的油量 a到达的最大路径假设是f那么我们可以得出 a b …...

String类基本使用

文章目录 1. String类的理解和创建对象2. 创建String对象的两种方式3. 两种创建String对象的区别4. 测试5. 字符串的特性6. String 类的常见方法 1. String类的理解和创建对象 String 对象用于保存字符串&#xff0c;也就是一组字符序列字符串常量对象是用双引号括起的字符序列…...

华为机试—火车进站

题目 火车站一共有 n 辆火车需要入站&#xff0c;每辆火车有一个编号&#xff0c;编号为 1 到 n。 同时&#xff0c;也有火车需要出站&#xff0c;由于火车站进出共享一个轨道&#xff0c;所以后入站的火车需要先出站。换句话说&#xff0c;对于某一辆火车&#xff0c;只有在它…...

Python数组(array)学习之旅:数据结构的奇妙冒险

Python数组学习之旅:数据结构的奇妙冒险 第一天:初识数组的惊喜 阳光透过窗帘缝隙洒进李明的房间,照亮了他桌上摊开的笔记本和笔记本电脑。作为一名刚刚转行的金融分析师,李明已经坚持学习Python编程一个月了。他的眼睛因为昨晚熬夜编程而微微发红,但脸上却挂着期待的微…...

spark-core编程2

Key-Value类型&#xff1a; foldByKey 当分区内计算规则和分区间计算规则相同时&#xff0c;aggregateByKey 就可以简化为 foldByKey combineByKey 最通用的对 key-value 型 rdd 进行聚集操作的聚集函数&#xff08;aggregation function&#xff09;。类似于aggregate()&…...