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

【12.MyBatis源码剖析与架构实战】1.核⼼流程源码剖析

MyBatis 核心流程源码剖析

MyBatis 作为一款优秀的持久层框架,通过封装 JDBC 的繁杂操作,让开发者只需专注于 SQL 本身。其核心流程分为两大阶段:初始化阶段(构建SqlSessionFactory)和执行阶段(通过SqlSession执行 SQL)。以下将结合源码对这两个阶段进行深度剖析。


一、初始化阶段:构建 SqlSessionFactory

MyBatis 的初始入口是SqlSessionFactoryBuilder,它负责解析配置文件并构建SqlSessionFactory

1.1 SqlSessionFactoryBuilder.build() 入口

// SqlSessionFactoryBuilder.javapublicSqlSessionFactorybuild(InputStreaminputStream,Stringenvironment,Propertiesproperties){try{// 创建 XMLConfigBuilder,用于解析 mybatis-config.xmlXMLConfigBuilderparser=newXMLConfigBuilder(inputStream,environment,properties);// 解析配置文件,生成 Configuration 对象Configurationconfiguration=parser.parse();// 构建 DefaultSqlSessionFactoryreturnbuild(configuration);}catch(Exceptione){throwExceptionFactory.wrapException("Error building SqlSession.",e);}finally{// 关闭输入流try{inputStream.close();}catch(IOExceptione){// ignore}}}

1.2 XMLConfigBuilder 解析配置文件

XMLConfigBuilder使用 XPath 解析 MyBatis 的核心配置文件,解析顺序如下:propertiessettingstypeAliasestypeHandlersobjectFactoryobjectWrapperFactoryreflectorFactorypluginsenvironmentsdatabaseIdProvidermappers

// XMLConfigBuilder.parse()publicConfigurationparse(){if(parsed){thrownewBuilderException("Each XMLConfigBuilder can only be used once.");}parsed=true;// 解析 configuration 节点parseConfiguration(parser.evalNode("/configuration"));returnconfiguration;}privatevoidparseConfiguration(XNoderoot){try{propertiesElement(root.evalNode("properties"));Propertiessettings=settingsAsProperties(root.evalNode("settings"));loadCustomVfs(settings);typeAliasesElement(root.evalNode("typeAliases"));pluginElement(root.evalNode("plugins"));objectFactoryElement(root.evalNode("objectFactory"));objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));reflectorFactoryElement(root.evalNode("reflectorFactory"));settingsElement(settings);environmentsElement(root.evalNode("environments"));databaseIdProviderElement(root.evalNode("databaseIdProvider"));typeHandlerElement(root.evalNode("typeHandlers"));mapperElement(root.evalNode("mappers"));}catch(Exceptione){thrownewBuilderException("Error parsing SQL Mapper Configuration. Cause: "+e,e);}}

核心对象:Configuration

Configuration是 MyBatis 中最重要的“容器类”,贯穿整个生命周期,存储了所有配置信息、Mapper 映射、类型处理器、插件等信息。

1.3 解析 Mapper 文件

mapperElement方法负责解析 Mapper 文件或注解接口:

// XMLConfigBuilder.mapperElement()privatevoidmapperElement(XNodeparent)throwsException{if(parent!=null){for(XNodechild:parent.getChildren()){if("package".equals(child.getName())){// 扫描包方式StringmapperPackage=child.getStringAttribute("name");configuration.addMappers(mapperPackage);}else{Stringresource=child.getStringAttribute("resource");Stringurl=child.getStringAttribute("url");StringmapperClass=child.getStringAttribute("class");if(resource!=null&&url==null&&mapperClass==null){// 资源方式:解析 XML 文件XMLMapperBuildermapperParser=newXMLMapperBuilder(Resources.getResourceAsStream(resource),configuration,resource,configuration.getSqlFragments());mapperParser.parse();}elseif(resource==null&&url!=null&&mapperClass==null){// URL 方式XMLMapperBuildermapperParser=newXMLMapperBuilder(Resources.getUrlAsStream(url),configuration,url,configuration.getSqlFragments());mapperParser.parse();}elseif(resource==null&&url==null&&mapperClass!=null){// 接口方式Class<?>mapperInterface=Resources.classForName(mapperClass);configuration.addMapper(mapperInterface);}}}}}

XMLMapperBuilder在解析 Mapper 文件时,会进一步解析 SQL 语句并构建MappedStatement

// XMLMapperBuilder.configurationElement()privatevoidconfigurationElement(XNodecontext){try{Stringnamespace=context.getStringAttribute("namespace");builderAssistant.setCurrentNamespace(namespace);cacheRefElement(context.evalNode("cache-ref"));cacheElement(context.evalNode("cache"));parameterMapElement(context.evalNodes("/mapper/parameterMap"));resultMapElement(context.evalNodes("/mapper/resultMap"));sqlElement(context.evalNodes("/mapper/sql"));// 解析 select | insert | update | delete 语句buildStatementFromContext(context.evalNodes("select|insert|update|delete"));}catch(Exceptione){thrownewBuilderException("Error parsing Mapper XML. Cause: "+e,e);}}

二、SQL 执行流程

SQL 执行的入口是SqlSession的 API 调用,核心组件分工明确:SqlSessionExecutorStatementHandlerParameterHandlerResultSetHandler

2.1 整体执行流程图

数据库交互层

核心执行层

业务层

未命中

命中

未命中

http://www.jsqmd.com/news/673819/

相关文章:

  • 2026长沙GEO优化公司TOP5榜单最新实力测评 - GEO优化
  • Joy-Con Toolkit完整指南:5步彻底掌握Switch手柄自定义与修复
  • BilibiliDown:免费跨平台B站视频下载终极指南,3分钟轻松掌握离线收藏技巧
  • 从BAM到动态图:用scVelo+velocyto玩转单细胞RNA速率分析(附完整R/Python代码)
  • Dify 客户端 AOT 发布后体积暴增2.4GB?——C# 14 三大 linker 指令深度调优(附.NET 9 RC2实测对比数据)
  • API密钥泄露率飙升47%?Dify 2026网关安全配置(2024Q3 CISA认证级实操手册)
  • 【.NET】本地化
  • AI与Agent开始接管重复性工作后,测试岗会不会成为最先被淘汰的岗位?
  • 匠行科技基于AMD Xilinx Kintex UltraScale系列FPGA XCKU060与TI KeyStone架构八核DSP TMS320C6678的6U CPCI异构多核高性能信号处理板卡
  • 3步解锁MusicBee完美歌词体验:网易云音乐插件终极指南
  • # WebGPU实战:从零构建高性能图形渲染管线(附完整代码与流程图)在现代Web应用中,**图形渲染性能
  • 从CentOS迁移到openEuler 22.03 LTS的Dify生产级部署——仅用1份Ansible Playbook+4个国产化补丁,实现零业务中断切换
  • I Have a Dream
  • 软件著作权主体指享有著作权的人,包括公民、法人和其他组织,对主体无行为能力限制,对外国人、无国籍人实行“有条件“国民待遇原则
  • Boost库配置后如何验证?一个多线程测试案例带你玩转VS2019
  • Java响应式编程革命再升级(Loom协程×Virtual Threads×Reactive Streams三重融合白皮书)
  • 告别u8/u16混乱:STM32F407标准库网络驱动向HAL库移植的类型定义避坑指南
  • 制品仓库管理:二进制文件的版本控制与分发策略
  • ArcGIS Pro 3.0 保姆级教程:用ModelBuilder批量处理气象nc文件,12个月数据一键导出为GeoTIFF
  • 如何在10分钟内用BallonsTranslator完成专业漫画翻译?简单三步搞定AI翻译工作流
  • 【12.MyBatis源码剖析与架构实战】19.MyBatis分⻚插件设计与实战
  • 拆解网红小风扇:它的‘边充边放’和‘过路保护’是怎么用一颗FS8A15S8 MCU实现的?
  • OSG+Qt实战:从官方osgviewerQt例子到自定义3D编辑器界面
  • Typora+LaTeX公式保姆级教程:从基础语法到复杂矩阵排版
  • 避坑指南:YOLOv5 v6.2训练分类模型时,关于数据集划分、种子复现和模型导出的几个关键细节
  • CarMaker for Simulink联合仿真实战:如何利用IPGMovie和Data Inspector实时调试你的车辆模型
  • 必看!2026有自主研发技术的GEO服务商推荐,避开外包坑 - 品牌测评鉴赏家
  • 保姆级教程:用Python和Basemap绘制台风‘利奇马’期间的卫星云图(附完整代码)
  • 用Arduino Nano和AD8232模块DIY一个心率监测手环(附完整代码与电路图)
  • 收藏!AI入行指南:小白程序员必备的岗位选择、技能树与学习路径