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

MyBatis的工作流程及源码连贯阅读方式

MyBatis 的工作流程可概括为以下核心步骤加载配置读取全局配置文件mybatis-config.xml解析数据源、事务管理器、映射文件mapper.xml或注解配置。创建 SqlSessionFactory使用配置信息构建SqlSessionFactory对象通常通过SqlSessionFactoryBuilder该对象是应用全局单例。获取 SqlSession从SqlSessionFactory中打开一个SqlSession代表一次数据库会话提供执行 SQL 的方法。获取 Mapper 代理对象通过SqlSession.getMapper(Class)为映射器接口生成动态代理对象代理内部调用SqlSession的 SQL 执行方法。执行 SQL调用 Mapper 接口中的方法代理底层会根据方法签名和参数通过SqlSession找到对应 SQL 语句依据命名空间和 ID并设置参数如#{param}占位符后交给 JDBC 执行。结果映射JDBC 返回结果集后MyBatis 自动将结果集映射为 Java 对象支持简单类型、Map、POJO 等并返回给调用方。事务控制与资源关闭业务代码中可显式提交/回滚事务最后关闭SqlSession释放数据库连接。核心思想将 SQL 与 Java 代码解耦通过动态代理和配置映射简化 JDBC 操作。连贯的源码阅读总体思路从 API 调用入手逐层跟进去阅读框架源码最好的方式是从一个最简单的可运行的 API 调用示例入手在 IDE 中开启 Debug 模式逐层跟进去。结合Mybatis3.5.x版本源码以这段经典代码为起点Stringresourcemybatis-config.xml;InputStreaminputStreamResources.getResourceAsStream(resource);// ① 构建 SqlSessionFactorySqlSessionFactorysqlSessionFactorynewSqlSessionFactoryBuilder().build(inputStream);// ② 打开 SqlSessiontry(SqlSessionsessionsqlSessionFactory.openSession()){// ③ 获取 Mapper 代理对象BusinessMappermappersession.getMapper(BusinessMapper.class);// ④ 执行 SQL 查询从这里开始 Debug 进入⭐Businessbusinessmapper.selectBusinessById(1);System.out.println(business);}调试入口点在mapper.selectBusinessById(1)这一行打上断点然后 Debug 运行IDE 会进入到 MapperProxy 等核心类中。三大阶段完整调用链路MyBatis 的源码执行路径可以分成三个连贯的大阶段各个阶段各自有清晰的入口和调用链。第一阶段启动与初始化 —— 入口SqlSessionFactoryBuilder.build()这是整个框架的建房子阶段把配置文件变成内存中的配置模型。入口类SqlSessionFactoryBuilder它使用了建造者模式有 9 个重载的build()方法用以不同的方式创建工厂对象。核心调用链追踪路线按顺序打断点即可SqlSessionFactoryBuilder.build(InputStream)这是用户代码中调用的第一个方法创建 XMLConfigBuilder 对象。XMLConfigBuilder.parse()先检查是否已被解析过然后调用parseConfiguration()方法。XMLConfigBuilder.parseConfiguration(XNode)重点关注 这里按照 MyBatis 全局配置文件的节点顺序逐一解析每个标签properties→settings→typeAliases→plugins→environments→mappers等。每解析一个标签就把解析结果存入Configuration对象中。XMLMapperBuilder.parse()当遇到mappers标签时会进入到具体的 Mapper 映射文件解析每个 Mapper XML 被解析成一条MappedStatement对象包含 SQL 语句、参数映射、结果映射等信息存入Configuration.mappedStatements集合中。SqlSessionFactoryBuilder.build(Configuration)最后用解析好的Configuration对象创建DefaultSqlSessionFactory并返回。第一阶段的目标很明确Configuration对象是这个阶段的核心产物其中包含了 MyBatis 运行所需的全部元数据信息。可以在XMLConfigBuilder.parseConfiguration()的不同方法中打断点看看各个标签是如何被一步步解析并填充到Configuration对象中的。第二阶段获取代理对象和执行入口 —— 入口DefaultSqlSession.getMapper()这一阶段是建立数据库操作指挥部当调用sqlSession.getMapper()时它为背后的 Mapper 接口凭空变出一个可以执行 SQL 的实现类。入口类DefaultSqlSession.getMapper(ClassT type)调用链连贯地跟进去DefaultSqlSession.getMapper()直接委托给configuration.getMapper(type, this)。Configuration.getMapper()内部调用mapperRegistry.getMapper(type, sqlSession)。MapperRegistry.getMapper()核心 JDK 动态代理的创建点先从knownMappers集合中根据接口类型找到对应的MapperProxyFactory。然后调用mapperProxyFactory.newInstance(sqlSession)创建代理对象。newInstance()方法内部return (T) Proxy.newProxyInstance(... , new MapperProxy())。MapperProxy类的构造与结构MapperProxy是 JDK 动态代理的InvocationHandler实现类。当代理对象的方法被调用时最终会执行MapperProxy.invoke()。在这里建议关注的点看看MapperRegistry.knownMappers是什么时候被填充的——这正是在第一阶段解析 Mapper 映射关系时完成的。第三阶段SQL 执行与结果映射—— 真正的数据库操作链路这是 MyBatis 源码中最长也最精彩的一条链路。当调用mapper.selectBusinessById(1)时IDE 进入了MapperProxy.invoke()。执行链完整顺序按顺序打断点跟进去步骤核心类/方法职责1. 动态代理拦截MapperProxy.invoke()拦截 Mapper 接口的方法调用2. 方法包装与路由MapperMethod.execute()根据 SQL 类型SELECT/INSERT/UPDATE/DELETE决定执行路径3. SqlSession 入口DefaultSqlSession.selectOne()委托给 Executor 执行4.缓存处理CachingExecutor.query()检查二级缓存跨 SqlSession 级别5.一级缓存BaseExecutor.query()检查一级缓存会话级别若未命中则调用子类的doQuery()6. 真正的查询逻辑SimpleExecutor.doQuery()创建 StatementHandler准备 JDBC 执行环境7.创建 StatementHandlerConfiguration.newStatementHandler()最终返回RoutingStatementHandler它内部包装了真正的PreparedStatementHandler8.参数绑定PreparedStatementHandler.parameterize()内部调用DefaultParameterHandler.setParameters()循环为PreparedStatement的?占位符赋值9. 执行 SQLPreparedStatementHandler.query()调用PreparedStatement.execute()获得ResultSet10.结果映射DefaultResultSetHandler.handleResultSets()将 JDBCResultSet转换为 Java 对象或集合返回11. 资源回收DefaultSqlSession.close()关闭数据库连接释放资源串联起来完整调用链可以概括为一句话SqlSession → MapperProxy → MappedStatement → Executor → StatementHandler → ParameterHandler → JDBC 执行 → ResultSetHandler → 返回结果。总结快速定位的关键点功能起点类核心方法配置加载XMLConfigBuilderparseConfiguration()代理生成MapperProxyFactorynewInstance()方法拦截MapperProxyinvoke()二级/一级缓存CachingExecutor/BaseExecutorquery()SQL 参数绑定DefaultParameterHandlersetParameters()JDBC 执行与结果映射PreparedStatementHandler/DefaultResultSetHandlerquery()→handleResultSets()通过这种方式不需要一步一个脚印地找断点而是跟着代码执行的顺序自然地走进 MyBatis 的每一个核心环节。

相关文章:

MyBatis的工作流程及源码连贯阅读方式

MyBatis 的工作流程可概括为以下核心步骤:加载配置 读取全局配置文件(mybatis-config.xml),解析数据源、事务管理器、映射文件(mapper.xml)或注解配置。创建 SqlSessionFactory 使用配置信息构建 SqlSessio…...

保姆级教程:给你的Oh My Zsh装上这4个插件,终端效率直接翻倍(附避坑指南)

终极效率指南:Oh My Zsh四大插件深度配置与实战技巧 如果你已经用上了Oh My Zsh但总觉得还能更高效,这篇文章就是为你准备的。想象一下:输入命令时自动补全、语法错误即时高亮显示、历史命令智能推荐——这些功能不是未来,而是今天…...

别再死记硬背五层需求了!用马斯洛理论设计产品,这3个实战案例让你秒懂

产品设计的底层密码:用马斯洛需求理论打造用户无法拒绝的体验 深夜两点,某社交App的产品经理盯着用户留存曲线发愁——明明新增功能增加了30%,次日留存率却下降了5个百分点。这场景你是否熟悉?当我们沉迷于功能堆砌和界面美化时&a…...

如何精准诊断并解决机械键盘连击问题:Keyboard Chatter Blocker深度配置指南

如何精准诊断并解决机械键盘连击问题:Keyboard Chatter Blocker深度配置指南 【免费下载链接】KeyboardChatterBlocker A handy quick tool for blocking mechanical keyboard chatter. 项目地址: https://gitcode.com/gh_mirrors/ke/KeyboardChatterBlocker …...

别再手动更新进度了!用Jira看板+自动化规则,5分钟搞定团队每日站会

敏捷团队效率革命:Jira自动化规则在每日站会中的高阶应用 每天早晨9:15分,TechLead张伟都会面临同样的困境——六位开发成员轮流汇报进度时,有人忘记更新Jira卡片状态,有人混淆了任务优先级,而作为Scrum Master的他不得…...

Ripes终极指南:掌握RISC-V处理器可视化仿真的完整教程

Ripes终极指南:掌握RISC-V处理器可视化仿真的完整教程 【免费下载链接】Ripes A graphical processor simulator and assembly editor for the RISC-V ISA 项目地址: https://gitcode.com/gh_mirrors/ri/Ripes 想要深入理解计算机体系结构却苦于抽象概念难以…...

鸣潮玩家每天浪费3小时?这款开源自动化工具让你轻松解放双手!

鸣潮玩家每天浪费3小时?这款开源自动化工具让你轻松解放双手! 【免费下载链接】ok-wuthering-waves 鸣潮 后台自动战斗 自动刷声骸 一键日常 Automation for Wuthering Waves 项目地址: https://gitcode.com/GitHub_Trending/ok/ok-wuthering-waves …...

SeekerClaw:在Android手机上本地部署全栈AI智能体的实践指南

1. 项目概述:一个运行在你手机里的全能AI副驾如果你和我一样,对AI Agent的潜力感到兴奋,但又厌倦了所有操作都必须通过云端API、受限于网络和延迟,那么SeekerClaw的出现绝对会让你眼前一亮。这不是另一个聊天机器人App&#xff0c…...

告别CANoe?手把手教你用Python+PCAN搭建汽车诊断脚本(附完整代码)

告别CANoe?用PythonPCAN实现汽车诊断自动化的实战指南 在汽车电子开发与测试领域,诊断协议一直是工程师们绕不开的核心技术。传统方案中,Vector CANoe凭借其完善的UDS诊断功能成为行业标配,但动辄数万的授权费用让许多个人开发者和…...

密钥管理体制PKI和KMI(二)

从信任机器到权力结构:密钥管理体制PKI与KMI的多维解构 引言:一个关于信任的认知迷局 假设你有一个装满绝密文件的保险柜。一种思路是,你给每个有权访问的人一把物理钥匙,由中央保安室统一登记、分发、收回——丢了钥匙立即注销。另一种思路是,你给每个人发一个不可伪造…...

从零到点亮LED:基于STM8S105K4T6C的STVD+COSMIC项目创建全流程实录

从零到点亮LED:基于STM8S105K4T6C的STVDCOSMIC项目创建全流程实录 第一次接触STM8S系列单片机时,我被它小巧的体积和丰富的功能所吸引。作为一个嵌入式开发新手,我决定从最基础的LED点亮实验开始,逐步掌握这个平台的开发流程。本文…...

PyQt-Fluent-Widgets:终极现代化桌面UI开发解决方案

PyQt-Fluent-Widgets:终极现代化桌面UI开发解决方案 【免费下载链接】PyQt-Fluent-Widgets A fluent design widgets library based on C Qt/PyQt/PySide. Make Qt Great Again. 项目地址: https://gitcode.com/gh_mirrors/py/PyQt-Fluent-Widgets 在桌面应用…...

创业团队如何利用统一 API 网关优化 AI 开发成本与效率

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 创业团队如何利用统一 API 网关优化 AI 开发成本与效率 对于资源有限的创业团队而言,在探索和集成人工智能能力时&…...

StreamFX实战进阶:如何解决OBS直播画面效果单一的深度指南

StreamFX实战进阶:如何解决OBS直播画面效果单一的深度指南 【免费下载链接】obs-StreamFX StreamFX is a plugin for OBS Studio which adds many new effects, filters, sources, transitions and encoders! Be it 3D Transform, Blur, complex Masking, or even c…...

别再只调颜色了!用STM32驱动SK6812/WS2812实现呼吸灯和流水灯(附完整代码)

突破基础点亮:STM32驱动SK6812/WS2812的进阶动画效果实战 从静态到动态的灯光艺术 当LED灯珠从简单的"亮与灭"升级为流畅的呼吸渐变和复杂的流水动画时,整个项目立刻拥有了生命力。对于嵌入式开发者而言,掌握SK6812/WS2812这类智…...

ArcGIS新手必看:别再搞混OBJECTID、FID和OID了,数据导出和连接的关键都在这

ArcGIS数据操作核心:深度解析OBJECTID、FID与OID的实战应用 当你第一次在ArcGIS中导出Shapefile到地理数据库时,是否遇到过表连接后数据神秘消失的情况?或者在进行多格式数据转换时,发现原本完美的空间关联突然失效?这…...

别再死记硬背了!用一张图帮你彻底搞懂AXI协议的五个通道(附通道交互时序详解)

一张图破解AXI协议:五通道交互逻辑与实战时序图解 第一次接触AXI协议时,看着文档里密密麻麻的信号线和五个通道缩写,我的大脑就像FPGA刚上电时的未初始化寄存器——一片混沌。直到在某个项目调试中,因为误解了写响应通道的时序导致…...

AI智能体框架Owletto:模块化设计与自动化运维实战

1. 项目概述:一个面向开发者的AI智能体框架最近在GitHub上闲逛,发现了一个挺有意思的项目,叫lobu-ai/owletto。乍一看这个名字,可能会有点摸不着头脑,但点进去研究一番后,发现它其实是一个定位非常清晰的AI…...

5分钟极速上手!NsEmuTools:NS模拟器一站式管理神器

5分钟极速上手!NsEmuTools:NS模拟器一站式管理神器 【免费下载链接】ns-emu-tools 一个用于安装/更新 NS 模拟器的工具 项目地址: https://gitcode.com/gh_mirrors/ns/ns-emu-tools 还在为NS模拟器的繁琐配置而烦恼吗?NsEmuTools就是为…...

从深度图到3D点云:用奥比中光摄像头和OpenNI玩转Python三维视觉(实战项目)

从深度图到3D点云:用奥比中光摄像头和OpenNI玩转Python三维视觉 当RGBD摄像头捕捉到的深度数据在屏幕上跳动时,那些数字背后隐藏着一个完整的三维世界。想象一下,你不仅能"看到"物体的平面图像,还能精确感知每个像素点…...

自动驾驶安全新维度:V2X通信如何破解人机混行困局

1. 项目概述:当自动驾驶遭遇“沟通障碍”如果你认为自动驾驶汽车和车与车之间的通信是两个独立的问题,那说明你的思考可能还停留在“非此即彼”的阶段。在汽车行业摸爬滚打十几年,我见过太多关于“全自动驾驶乌托邦”的宏大叙事:零…...

告别软核!用Zynq UltraScale+ MPSoC EV系列硬核VCU搞定4K60 H.265编解码

硬核加速:Zynq UltraScale MPSoC EV系列VCU在4K60视频处理中的实战解析 当4K60fps视频处理成为工业视觉、自动驾驶和广电传媒的标配需求时,工程师们往往陷入两难:通用处理器难以应对实时编解码的计算洪流,而传统FPGA软核方案又面…...

MelonLoader终极指南:如何为Unity游戏安装和管理模组

MelonLoader终极指南:如何为Unity游戏安装和管理模组 【免费下载链接】MelonLoader The Worlds First Universal Mod Loader for Unity Games compatible with both Il2Cpp and Mono 项目地址: https://gitcode.com/gh_mirrors/me/MelonLoader MelonLoader是…...

如何利用社区清单选择优质主机:从概念到实战的完整指南

1. 项目概述:为什么我们需要一份“优质主机”清单?在数字世界安家落户,无论是搭建个人博客、部署一个实验性的Web应用,还是运营一个初创公司的在线业务,第一步总是绕不开一个最基础也最让人头疼的问题:选择…...

Cursor IDE 一键登录扩展:基于 JWT 令牌的浏览器自动化实践

1. 项目概述:一个专为 Cursor IDE 设计的浏览器扩展 如果你和我一样,是 Cursor IDE 的深度用户,并且手头管理着不止一个账号(比如个人账号、公司账号、测试账号),那你一定对频繁登录 Cursor 仪表盘&#x…...

一键解锁九大网盘下载自由:LinkSwift完全攻略

一键解锁九大网盘下载自由:LinkSwift完全攻略 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 / 迅…...

基于Go的轻量级心跳监控服务:moltbook-heartbeat架构与实践

1. 项目概述:一个轻量级的心跳检测服务最近在搞一个分布式系统的监控,发现服务实例的健康状态管理是个挺头疼的事儿。手动去查日志、看进程,效率低不说,还容易漏掉关键节点。后来在GitHub上翻到了terryso/moltbook-heartbeat这个项…...

别再被DLL报错劝退!VS2022配置SFML 2.6.0图形库的完整避坑指南

别再被DLL报错劝退!VS2022配置SFML 2.6.0图形库的完整避坑指南 如果你正在学习C游戏开发,SFML绝对是一个不可错过的图形库。它轻量、跨平台,而且API设计优雅,是初学者进入游戏编程世界的绝佳选择。然而,许多开发者——…...

中小团队如何利用Taotoken实现多模型成本与用量可控

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 中小团队如何利用Taotoken实现多模型成本与用量可控 对于预算与资源有限的中小开发团队而言,直接对接多个大模型厂商的…...

5分钟免费美化VLC播放器:VeLoCity皮肤终极美化完整指南

5分钟免费美化VLC播放器:VeLoCity皮肤终极美化完整指南 【免费下载链接】VeLoCity-Skin-for-VLC Castom skin for VLC Player 项目地址: https://gitcode.com/gh_mirrors/ve/VeLoCity-Skin-for-VLC 厌倦了VLC播放器千篇一律的默认界面?想让你的影…...