mybatis标签解析教程

news2025/1/24 8:32:59

mybatis标签解析

标签结构

我们在mapper的xml文件中,使用动态SQL,那么这些标签<where>、<if>、<set>、<ForEach>、<Choose>、<Trim> 等是怎么解析的呢?我们先看包的结构
在这里插入图片描述

包结构中,script -> xmltags 便是这些动态标签对象,我们在看看这些动态的tag的关系,如下

在这里插入图片描述

SqlNode类如下

public interface SqlNode {
  boolean apply(DynamicContext context);
}

标签处理器

现在那么是如何解析这些的呢?

public class XMLScriptBuilder extends BaseBuilder {

  private final XNode context;
  private boolean isDynamic; //是否是动态sql, 根据占位符#{},${}来判断,有就是动态的
  private final Class<?> parameterType;
  private final Map<String, NodeHandler> nodeHandlerMap = new HashMap<>();


  public XMLScriptBuilder(Configuration configuration, XNode context, Class<?> parameterType) {
    super(configuration);
    this.context = context;
    this.parameterType = parameterType;
    //初始化的标签处理器 
    initNodeHandlerMap();
  }

  private void initNodeHandlerMap() {
    nodeHandlerMap.put("trim", new TrimHandler());
    nodeHandlerMap.put("where", new WhereHandler());
    nodeHandlerMap.put("set", new SetHandler());
    nodeHandlerMap.put("foreach", new ForEachHandler());
    nodeHandlerMap.put("if", new IfHandler());
    nodeHandlerMap.put("choose", new ChooseHandler());
    nodeHandlerMap.put("when", new IfHandler());
    nodeHandlerMap.put("otherwise", new OtherwiseHandler());
    nodeHandlerMap.put("bind", new BindHandler());
  }
}

我们看看这些标签处理器,都实现了NodeHandler接口

public class XMLScriptBuilder extends BaseBuilder {

 //内部类NodeHandler,提供了各种具体的标签Handler
  private interface NodeHandler {
    void handleNode(XNode nodeToHandle, List<SqlNode> targetContents);
  }

  private class BindHandler implements NodeHandler {}

  private class TrimHandler implements NodeHandler {}

  private class WhereHandler implements NodeHandler {}

  private class SetHandler implements NodeHandler {}

  private class ForEachHandler implements NodeHandler {}

  private class IfHandler implements NodeHandler {}

  private class OtherwiseHandler implements NodeHandler {}

  private class ChooseHandler implements NodeHandler {}
}

where 标签示例

我们用 where 标签示例,解析的时候根据xml中node的名称where名称获取对应的Handler,也就是WhereHandler

private class WhereHandler implements NodeHandler {
    public WhereHandler() {
      // Prevent Synthetic Access
    }

    @Override
    public void handleNode(XNode nodeToHandle, List<SqlNode> targetContents) {
      MixedSqlNode mixedSqlNode = parseDynamicTags(nodeToHandle);
      //解析where标签,mixedSqlNode 就是where标签里面的内容
      WhereSqlNode where = new WhereSqlNode(configuration, mixedSqlNode);
      targetContents.add(where);
    }
  }

我们继续看下这个WhereSqlNode是怎么处理的

public class WhereSqlNode extends TrimSqlNode {

    //前缀,目测是删除where条件后面的第一个运算法,where and a = 1 这种情况
  private static List<String> prefixList = Arrays.asList("AND ","OR ","AND\n", "OR\n", "AND\r", "OR\r", "AND\t", "OR\t");

  public WhereSqlNode(Configuration configuration, SqlNode contents) {
    super(configuration, contents, "WHERE", prefixList, null, null);
  }
}

我们看到是直接走父类TrimSqlNode去了

public void applyAll() {
  sqlBuffer = new StringBuilder(sqlBuffer.toString().trim());
  String trimmedUppercaseSql = sqlBuffer.toString().toUpperCase(Locale.ENGLISH);
  if (trimmedUppercaseSql.length() > 0) {
    applyPrefix(sqlBuffer, trimmedUppercaseSql);
    applySuffix(sqlBuffer, trimmedUppercaseSql);
  }
  delegate.appendSql(sqlBuffer.toString());
}

private void applyPrefix(StringBuilder sql, String trimmedUppercaseSql) {
  if (!prefixApplied) {
    prefixApplied = true;
    if (prefixesToOverride != null) {
      //遍历运算符,删除where前缀
      for (String toRemove : prefixesToOverride) {
        if (trimmedUppercaseSql.startsWith(toRemove)) {
          sql.delete(0, toRemove.trim().length());
          break;
        }
      }
    }
    if (prefix != null) {
      sql.insert(0, " ");//首位添加空格
      sql.insert(0, prefix);//然后添加where
    }
  }
}

到此解析完成

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1556238.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法沉淀——拓扑排序

前言&#xff1a; 首先我们需要知道什么是拓扑排序&#xff1f; 在正式讲解拓扑排序这个算法之前&#xff0c;我们需要了解一些前置知识&#xff08;和离散数学相关&#xff09; 1、有向无环图&#xff1a; 指的是一个无回路的有向图。 入度&#xff1a;有向图中某点作为图…

微服务(基础篇-007-RabbitMQ部署指南)

目录 05-RabbitMQ快速入门--介绍和安装_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1LQ4y127n4?p65&vd_source60a35a11f813c6dff0b76089e5e138cc 1.单机部署 1.1.下载镜像 1.2.安装MQ 2.集群部署 2.1.集群分类 2.2.设置网络 视频地址&#xff1a; 05-Rab…

Topaz Gigapixel AI for Mac 图像放大软件

Topaz Gigapixel AI for Mac是一款专为Mac用户设计的智能图像放大软件。它采用了人工智能技术&#xff0c;特别是深度学习算法&#xff0c;以提高图像的分辨率和质量&#xff0c;使得图像在放大后仍能保持清晰的细节。这款软件的特点在于其能够将低分辨率的图片放大至高分辨率&…

银河麒麟V10:sudo: /usr/bin/sudo 必须属于用户 ID 0(的用户)并且设置 setuid 位

一、引起原因&#xff1a; sudo chmod -R 777 bin 修改了/usr/bin/sudo的权限&#xff0c;引发后续问题。 二、现象&#xff1a; sudo执行命令报错&#xff1a; sudo: /usr/bin/sudo 必须属于用户 ID 0(的用户)并且设置 setuid 位 三、解决方法&#xff08;知道root密码&…

Java复习第十四天学习笔记(CSS),附有道云笔记链接

【有道云笔记】十四 3.30 CSS https://note.youdao.com/s/3VormGXs 一、CSS定义和基本选择器 CSS定义&#xff1a;cascading style sheet 层叠样式表。 语法&#xff1a; 选择器 { 属性名1:属性值1; 属性名2:属性值2; 属性名3:属性值3; 属性名4:属性值4; } CSS使用&a…

经典永不过时 Wordpress模板主题

经得住时间考验的模板&#xff0c;才是经典模板&#xff0c;带得来客户的网站&#xff0c;才叫NB网站。 https://www.jianzhanpress.com/?p2484

基于大数据的学习资源推荐系统的设计与实现(论文+源码)_kaic

摘 要 本文首先实现了学习资源推送管理技术的发展&#xff0c;随后依照传统的软件开发流程&#xff0c;最先为系统挑选适用的语言和软件开发平台&#xff0c;依据需求分析开展控制模块制作和数据库查询构造设计&#xff0c;依据系统整体功能模块的设计&#xff0c;制作系统的功…

武汉星起航引领亚马逊跨境电商新浪潮,助推卖家向全球拓展

在全球化的浪潮中&#xff0c;跨境电商以其独特的魅力和无限潜力&#xff0c;正成为推动国际贸易发展的重要引擎。亚马逊&#xff0c;作为全球电商平台的佼佼者&#xff0c;以其卓越的技术、高效的服务和广阔的市场覆盖&#xff0c;引领着跨境电商的新风潮。而在这股风潮中&…

JUC并发编程——对于synchronized关键字的理解

现象&#x1f50d;&#xff1a; 两个线程对初始值为 0 的静态变量一个做自增&#xff0c;一个做自减&#xff0c;各做 5000 次&#xff0c;最后输出的 counter一定为0 吗&#xff1f; Slf4j(topic "c.Test17") public class Test17 {static int counter 0;public…

Js逆向简单分析-某网站登录案例

文章目录 概要整体流程1.打开网站&#xff0c;输入数据进行登录2.对getlogin.php进行查看分析3.对于登录请求连接进行断点调试4.堆栈跟踪5.在网络上找在线md5加密 友情推荐 概要 某网站登录流量包逆向分析。 整体流程 1.打开网站&#xff0c;输入数据进行登录 用户名&#…

【C语言基础】:自定义类型(一)--> 结构体

文章目录 一、内置类型与自定义类型1.1 内置类型&#xff08;基本数据类型&#xff09;1.2 自定义类型 二、结构体2.1 结构体的声明2.2 结构体变量的创建和初始化2.3 结构体的特殊声明2.4 结构体的自引用 三、结构体内存对齐3.1 对齐规则3.2 为什么存在内存对齐3.3 修改默认对齐…

基于java+SpringBoot+Vue的校友社交系统设计与实现

基于javaSpringBootVue的校友社交系统设计与实现 开发语言: Java 数据库: MySQL技术: SpringBoot MyBatis工具: IDEA/Eclipse、Navicat、Maven 系统展示 前台展示 后台展示 系统简介 整体功能包含&#xff1a; 校友社交系统是一个为校友提供一个交流互动、信息共享的平台…

【高数】汤家凤高等数学辅导讲义+1800错题整理

第一章 极限与连续 1. 2. 3. 4. 5. 6. 7. 第二章 导数与微分 高等数学辅导讲义 1. 2. 3. 4. 5. 6. 7. 8. 1800 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 第三章 一元函数微分学的应用 高等数学辅导讲义 中值定理 题型一 题型二 题型三 题型四 题型五 单调性、极值与…

三菱GX WORKS3连接FX5U系列PLC时,弹出窗口提示:用户认证功能或安全性强化模式未启用

三菱GX WORKS3连接FX5U系列PLC时&#xff0c;弹出窗口提示&#xff1a;用户认证功能或安全性强化模式未启用 如下图所示&#xff0c;使用GX WORKS3编程软件连接FX5U系列PLC&#xff0c; 首先&#xff0c;在连接目标中选择自己当前使用的网卡适配器&#xff0c;并将IP地址设置在…

HuTool工具箱验证JWT生成Token失败

系列文章目录 文章目录 系列文章目录前言前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于…

IC-随便记

1、移远通信---通信模组 物联网解决方案供应商&#xff0c;可提供完备的IoT产品和服务&#xff0c;涵盖蜂窝模组(5G/4G/3G/2G/LPWA)、车载前装模组、智能模组&#xff08;5G/4G/边缘计算&#xff09;、短距离通信模组(Wi-Fi&BT)、GNSS定位模组、卫星通信模组、天线等硬件产…

【全栈小5】我的创作纪念日

目录 前言机缘收获粉丝和原创个人成就六边形战士 回顾文章原代码代码优化 憧憬 前言 全栈小5 &#xff0c;有幸再次遇见你&#xff1a; 还记得 2019 年 03 月 29 日吗&#xff1f; 你撰写了第 1 篇技术博客&#xff1a; 《前端 - 仿动态效果 - 展开信息图标》 在这平凡的一天&…

直播上瘾?

目前我们正处在日新月异高速发展的时代&#xff0c;各行各业都在接入 AI&#xff0c;各行各业都在涌向直播的时代。当然&#xff0c;历史的车轮不会因为个人的喜好而改变&#xff0c;我们唯一能做的就是拥抱变化&#xff0c;这样才不会活的很别扭。 “ PS&#xff1a;这就是我为…

网络安全:绕过 MSF 的一次渗透测试

这次渗透的主站是 一个 Discuz!3.4 的搭建 违法招 piao 网站&#xff0c; 配置有宝塔 WAF 用 Discuz!ML 3.X 的漏洞进行攻击&#xff0c;但是没有成功 发现主站外链会有一个发卡网&#xff0c;引导人们来这充值&#xff0c;是 某某发卡网&#xff0c;而且域名指向也是主站的 ip…

一篇文章带你搞定企业级完整性能测试流程!

大部分公司在最初试的阶段只会关心项目的基本功能&#xff0c;能用就可以。但是随着项目的成熟&#xff0c;用户量逐步的增大&#xff0c;线上经常就会出现一些系统崩溃&#xff0c;用户反映系统太慢等性能问题的爆发。所以&#xff0c;性能测试的需求就逐步变得迫切了。所以&a…