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

【12.MyBatis源码剖析与架构实战】15.1 if和where标签执⾏过程剖析-初始化时

在 MyBatis 中,<if><where>标签在初始化阶段被解析为IfSqlNodeWhereSqlNode对象,并纳入语法树。下面将从入口调用NodeHandler 注册机制标签处理逻辑三个层面,结合底层源码和流程图进行剖析。

一、初始化阶段入口:从 XMLScriptBuilder 开始

MyBatis 启动时通过XMLScriptBuilder.parseDynamicTags()方法解析 SQL 节点。该方法接收一个 XNode 参数(代表整个<select><insert>等 SQL 语句节点),遍历其所有子节点,将文本节点和元素节点分别转换为对应的 SqlNode 对象,存入List<SqlNode>集合中,最终包装为MixedSqlNode作为语法树的根节点。

核心判断逻辑如下:

  • 文本节点:直接封装为StaticTextSqlNode(静态文本)或TextSqlNode(含${}的动态文本)。
  • 元素节点:通过节点名称(如ifwhereforeach)从nodeHandlerMap中获取对应的NodeHandler处理,一旦遇到任何元素节点,就标记isDynamic = true,最终创建DynamicSqlSource

二、NodeHandler 注册机制

XMLScriptBuilder在构造时会调用initNodeHandlerMap()方法,将所有动态标签与对应的NodeHandler实现类进行映射绑定:

// XMLScriptBuilder.initNodeHandlerMap()Map<String,NodeHandler>map=newHashMap<>();map.put("trim",newTrimHandler());map.put("where",newWhereHandler());map.put("set",newSetHandler());map.put("foreach",newForEachHandler());map.put("if",newIfHandler());map.put("choose",newChooseHandler());// ...

当解析到where节点时,nodeHandlerMap.get("where")返回WhereHandler;解析到if节点时,返回IfHandler。这种设计使得新增动态标签只需增加一个NodeHandler实现并注册即可,符合开闭原则

三、WhereHandler:解析 标签

WhereHandlerXMLScriptBuilder的内部类,负责处理<where>标签:

privateclassWhereHandlerimplementsNodeHandler{publicWhereHandler(){}@OverridepublicvoidhandleNode(XNodenodeToHandle,List<SqlNode>targetContents){// 1. 递归解析 <where> 节点内部的子内容,生成 MixedSqlNodeMixedSqlNodemixedSqlNode=parseDynamicTags(nodeToHandle);// 2. 创建 WhereSqlNode,将 mixedSqlNode 作为其内部 contentsWhereSqlNodewhere=newWhereSqlNode(configuration,mixedSqlNode);// 3. 将 WhereSqlNode 添加到父级 contents 列表中targetContents.add(where);}}

核心流程:

  1. 递归解析:调用parseDynamicTags(nodeToHandle)解析<where>标签内部的 SQL 片段(如<if>标签和静态文本),生成一个MixedSqlNode
  2. 构建 WhereSqlNode:将MixedSqlNode作为构造参数传入WhereSqlNodeWhereSqlNode本质上是TrimSqlNode的子类,预设了前缀"WHERE"以及需要覆盖的前缀列表AND |OR
  3. 挂载到父级:将创建好的WhereSqlNode添加到targetContents中,成为语法树的一部分。

四、IfHandler:解析 标签

IfHandler同样定义在XMLScriptBuilder内部,负责处理<if test="...">标签:

privateclassIfHandlerimplementsNodeHandler{@OverridepublicvoidhandleNode(XNodenodeToHandle,List<SqlNode>targetContents){// 1. 递归解析 <if> 节点内部的子内容,生成 MixedSqlNodeMixedSqlNodemixedSqlNode=parseDynamicTags(nodeToHandle);// 2. 获取 test 属性值Stringtest=nodeToHandle.getStringAttribute("test");// 3. 创建 IfSqlNodeIfSqlNodeifSqlNode=newIfSqlNode(mixedSqlNode,test);// 4. 将 IfSqlNode 添加到父级 contents 列表中targetContents.add(ifSqlNode);}}

核心流程:

  1. 递归解析:同样调用parseDynamicTags(nodeToHandle)解析<if>内部的 SQL 片段,生成MixedSqlNode
  2. 获取条件表达式:从 XML 节点中读取test属性值(OGNL 表达式),用于运行时条件判断。
  3. 构建 IfSqlNode:将解析得到的MixedSqlNodetest表达式传入构造器。IfSqlNode在运行时通过ExpressionEvaluatortest表达式求值,决定是否将内部 SQL 片段拼接到最终 SQL 中。
  4. 挂载到父级:将IfSqlNode添加到父级contents列表中。

五、完整解析流程 UML 流程图

http://www.cnnetsun.cn/news/1952101.html

相关文章:

  • Day8 trim方法String的偏底层字符串常量池intern方法装箱拆箱集合的ArrayList,LinkedListStringBuilder/Buffer
  • 避坑!这些毕设太好抄了,3000+毕设案例推荐第1071期
  • 细胞造万物:当生物制造成为“十五五”新风口,我们如何抓住30万亿美元的未来?
  • 【Agent】智能体基础入门(技术发展路线+TAO循环+function calling)
  • 豆包 LeetCode 1444.切披萨的方案数 public int ways(String[] pizza, int k)
  • HCIP学习19 BGP 跨自治系统互通综合实验
  • RabbitMQ实战:极端场景下消息零丢失全攻略——生产级完整方案
  • 别再只盯着零偏了!IMU选型中那些被忽视的‘隐形杀手’:振动敏感度与温度漂移实战分析
  • 机器学习模型泛化难题:从欠拟合到过拟合的实战诊断与调优
  • 从NS方程到润滑膜压力:雷诺方程推导与有限差分法求解实践
  • Playwright登录态复用:从Pytest Fixture到Page Object模式的工程实践
  • 深入WebRTC音频处理内核:从频谱平坦度到维纳滤波,一次搞懂ns_core.c的降噪逻辑
  • 从PWM到模拟信号:低通滤波器设计的工程实践与参数权衡
  • 不只是仿真:挖掘Icarus Verilog (iverilog) 的隐藏技能,比如把Verilog代码转成VHDL
  • W800开发板到手别慌,3天搞定开发环境与固件下载(保姆级避坑指南)
  • 低代码平台,开启企业数字化创新新时代!
  • 手把手教你:神州数码DCN无线AP从开箱到上线(附静态IP配置与AC二层发现避坑指南)
  • 避坑指南:Amos路径分析输出结果里,这5个常被忽略的参数(如Condition Number, M.I.)才是模型好坏的‘隐藏裁判’
  • 收藏备用|Java程序员转型大模型开发全指南(小白/资深开发者通用)
  • 火速报名 | 2026中国高校计算机大赛——大数据挑战赛,五星级巅峰对决,邀您问鼎!
  • OBS多平台直播终极指南:免费插件完整使用教程
  • 从零到一:前端集成腾讯云IM SDK构建实时会话功能
  • MATLAB调用C++ DLL实战:手把手教你用VS2017生成并集成到Simulink模型(附MinGW-w64安装避坑)
  • 保姆级教程:用Arduino IDE给ESP32安装开发环境,避开国内网络下载坑
  • 深入STM32F429的‘网络心脏’:图解MAC与PHY如何协同工作(附MII/RMII接口详解)
  • 3D 地球卫星轨道可视化平台开发 Day1(3D 场景、卫星渲染与筛选交互实现)
  • 阿里立下五年1000亿美元云和AI商业化目标,“HappyHorse”能助力阿里云打赢硬仗吗?
  • 深度剖析:LangGraph中的状态管理与循环逻辑
  • 自然语言即代码?SITS2026实测TOP3模型准确率骤降47%:从Prompt工程到编译验证的全链路调优手册
  • 技能(skill)与智能体(agent):AI时代的专业分工