ShardingSphere解析SQL示例详解

目录
  • 引言
  • 解析Sql的入口
  • 解析Sql
    • 1. 将 SQL 解析为抽象语法树
    • 2. 提取Sql片段
    • 3. 填充Sql片段,生成解析结果
  • 总结

引言

ShardingSphere的SQL解析,本篇文章源码基于4.0.1版本

ShardingSphere的分片引擎从解析引擎到路由引擎到改写引擎到执行引擎再到归并引擎,一步一步对分片操作进行处理,我们这篇文章先从解析引擎开始,深入分析一下Sql的解析引擎处理流程。

解析Sql的入口

SQLParseEngine这个类是sql解析引擎对应的类,通过看它的parse()方法,我们知道sql解析的过程就是构建SQLStatement对象的过程,方法中调用了SQLParseKernel来创建对象,然后调用它的parse()方法来完成。因此我们把重心放在这个方法上

解析Sql

SQLParseKernel的parse()方法:

public SQLStatement parse() {
    SQLAST ast = parserEngine.parse();
    Collection<SQLSegment> sqlSegments = extractorEngine.extract(ast);
    Map<ParserRuleContext, Integer> parameterMarkerIndexes = ast.getParameterMarkerIndexes();
    return fillerEngine.fill(sqlSegments, parameterMarkerIndexes.size(), ast.getSqlStatementRule());
}
  • 将原始SQL通过解析器解析为抽象语法树
  • 使用提取器根据提取规则提取Sql片段结合
  • 使用填充器根据填充规则填充Sql片段生成SQL解析后的结果并返回

下面将具体看一下这三步

1. 将 SQL 解析为抽象语法树

这一块是对应的SQLParserEngine的parse()方法,这个方法的主要逻辑是利用工厂类SQLParserFactory来创建Sql解析器实例,由于不同的数据库对应的SQL解析器也不相同,所以这一块的逻辑也是利用了Java的SPI机制来创建配置的SQLParserEntry实例对象,根据不同的数据库类型选择不同的Sql解析器,最终会生成SQLAST对象,也就是SQL 的抽象语法树。

2. 提取Sql片段

这一步对应的是SQLSegmentsExtractorEngine的extract()方法,返回的是所有的Sql片段的集合。

遍历抽象语法树中的Sql片段的提取器,提取器分为两种类型,一种是单节点的Sql片段提取器,这时候就直接获取Sql片段,放入集合中就可以了,另一种是树状节点的Sql片段提取线,这时候就需要遍历这棵树,将结果放入集合中。看!数据结构之树的遍历用到了吧,以后别说数据结构没用了。。

3. 填充Sql片段,生成解析结果

第三步就是填充得到的Sql片段了,对应的是SQLStatementFillerEngine的fill()方法

public SQLStatement fill(final Collection<SQLSegment> sqlSegments, final int parameterMarkerCount, final SQLStatementRule rule) {
    SQLStatement result = rule.getSqlStatementClass().newInstance();
    Preconditions.checkArgument(result instanceof AbstractSQLStatement, "%s must extends AbstractSQLStatement", result.getClass().getName());
    ((AbstractSQLStatement) result).setParametersCount(parameterMarkerCount);
    result.getAllSQLSegments().addAll(sqlSegments);
    for (SQLSegment each : sqlSegments) {
        Optional<SQLSegmentFiller> filler = parseRuleRegistry.findSQLSegmentFiller(databaseTypeName, each.getClass());
        if (filler.isPresent()) {
            filler.get().fill(each, result);
        }
    }
    return result;
}
  • 获取SQLStatement对象,对SQLStatement进行合法性进行校验
  • 设置结果的参数的个数
  • 将上一步中的SQL片段集合添加到结果对象中
  • 遍历Sql片段,根据数据库类型和Sql片段找到Sql片段过滤器,利用Sql片段过滤器来填充Sql片段
  • 最后返回解析后的SQLStatement

总结

这篇文章我们讲了ShardingSphere的解析Sql的功能,从它的入口开始到它具体解析Sql的过程,分三步走,第一步将原始SQL解析成抽象语法树,第二步提取Sql片段,第三步根据数据库类型和Sql片段选择相应的填充器填充Sql片段,这就是解析Sql的整体过程了,希望对你理解ShardingSphere有所帮助。

更多关于ShardingSphere SQL的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java基于ShardingSphere实现分库分表的实例详解

    目录 一.简介 二.项目使用 1.引入依赖 2.数据库 3.实体类 4.mapper 5.yml配置 6.测试类 7.数据 一.简介   Apache ShardingSphere 是一套开源的分布式数据库解决方案组成的生态圈,它由 JDBC.Proxy 和 Sidecar(规划中)这 3 款既能够独立部署,又支持混合部署配合使用的产品组成. 它们均提供标准化的数据水平扩展.分布式事务和分布式治理等功能,可适用于如 Java 同构.异构语言.云原生等各种多样化的应用场景.   Apache Sh

  • ShardingSphere jdbc集成多数据源的实现步骤

    目录 集成sharding jdbc 1. 引入依赖 2. 配置分表规则 问题 集成多数据源 1. 引入依赖 2. 多数据源配置 3. 增加多数据源配置 4. 使用 总结 最近有个项目的几张表,数量级在千万以上,技术栈是SpringBoot+Mybatis-plus+MySQL.如果使用单表,在进行查询操作,非常耗时,经过一番调研,决定使用分表中间件:ShardingSphere. ShardingSphere今年4月份成为了 Apache 软件基金会的顶级项目,目前支持数据分片.读写分离.多数

  • 使用shardingsphere对SQLServer坑的解决

    背景:最近一个使用SQLServer的项目,业务量太大,开始对业务有影响了,因此用户要求升级改造,技术上采用shardingsphere进行分库分表. 经过一系列调研,设计...哐哐一顿操作之后开始动刀改造.pom依赖如下: <!--sharding--> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-

  • 使用ShardingSphere-Proxy实现分表分库

    目录 1.环境准备 2.数据库脚本准备 3.配置ShardingSphere-Proxy 分表原理解析 参考:Sharding-Proxy的基本功能使用 1. 环境准备 MySql 5.7 apache-shardingsphere-4.1.1-sharding-proxy-bin.tar.gz jdk 1.8 mysql-connector-java-5.1.49.jar 2. 数据库脚本准备 # 创建商品数据库 CREATE DATABASE IF NOT EXISTS `products`

  • SpringBoot整合ShardingSphere的示例代码

    目录 一.相关依赖 二.Nacos数据源配置 三.项目配置 四.验证 概要: ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC.Sharding-Proxy和Sharding-Sidecar(计划中)这3款相互独立的产品组成. 他们均提供标准化的数据分片.分布式事务和数据库治理功能,可适用于如Java同构.异构语言.云原生等各种多样化的应用场景. 官网地址:https://shardingsphere.apache.org/ 一.相关

  • ShardingSphere解析SQL示例详解

    目录 引言 解析Sql的入口 解析Sql 1. 将 SQL 解析为抽象语法树 2. 提取Sql片段 3. 填充Sql片段,生成解析结果 总结 引言 ShardingSphere的SQL解析,本篇文章源码基于4.0.1版本 ShardingSphere的分片引擎从解析引擎到路由引擎到改写引擎到执行引擎再到归并引擎,一步一步对分片操作进行处理,我们这篇文章先从解析引擎开始,深入分析一下Sql的解析引擎处理流程. 解析Sql的入口 SQLParseEngine这个类是sql解析引擎对应的类,通过看它的

  • golang gorm更新日志执行SQL示例详解

    目录 1. 更新日志 1.1. v1.0 1.1.1. 破坏性变更 gorm执行sql 1. 更新日志 1.1. v1.0 1.1.1. 破坏性变更 gorm.Open返回类型为*gorm.DB而不是gorm.DB 更新只会更新更改的字段 大多数应用程序不会受到影响,只有当您更改回调中的更新值(如BeforeSave,BeforeUpdate)时,应该使用scope.SetColumn,例如: func (user *User) BeforeUpdate(scope *gorm.Scope) {

  • QT+ffmpeg实现视频解析的示例详解

    目录 一.创建QT项目 二.引入ffmpeg 1.复制头文件和lib 2.复制bin文件 3.简单测试 三.视频解析 1.创建线程 2.创建自定义绘制控件 3.使用自定义控件 4.开启线程,进行视频解析 一.创建QT项目 首先安装了最新的Community版本,Creator是8.0.1版本了. 然后进行项目的创建. 得到的项目没有pro文件,而是CMakeLists.txt. 二.引入ffmpeg 从下面下载的ffmpeg-5.0.1-full_build-shared.7z. https:/

  • C++实现xml解析器示例详解

    目录 xml格式简单介绍 xml格式解析过程浅析 代码实现 实现存储解析数据的类——Element 关键代码1——实现整体的解析 关键代码2——解析所有元素 开发技巧 有关C++的优化 额外注意 xml格式简单介绍 <?xml version="1.0"?> <!--这是注释--> <workflow> <work name="1" switch="on"> <plugin name=&quo

  • java开发ShardingSphere的路由引擎类型示例详解

    目录 ShardingSphere的路由引擎类型 路由引擎类型 标准路由 路由逻辑 总结 ShardingSphere的路由引擎类型 本篇文章源码基于4.0.1版本 上篇文章我们了解到了ShardingSphere在路由流程过程中,根据不同类型的SQL会现在不同的路由引擎,而ShardingSphere支持的路由规则也很多了,包括广播(broadcast)路由.混合(complex)路由.默认数据库(defaultdb)路由.无效(ignore)路由.标准(standard)路由以及单播(uni

  • SQL实现Excel的10个常用功能的示例详解

    目录 01. 关联公式:Vlookup 02. 对比两列差异 03. 去除重复值 04. 缺失值处理 05. 多条件筛选 06. 模糊筛选数据 07. 分类汇总 08. 条件计算 09. 删除数据间的空格 10. 合并与排序列 SQL笔试题原题 某数据服务公司 某手游公司的SQL笔试题(原题) 某互联网金融公司SQL笔试题(原题) SQL,数据分析岗的必备技能,你可以不懂Python,R,不懂可视化,不懂机器学习.但SQL,你必须懂.要不然领导让你跑个数据来汇......,哦不,你不懂SQL都无

  • Python实现解析yaml配置文件的示例详解

    目录 楔子 字典 数组 标量 引用 生成 yaml 文件 楔子 前面我们介绍了 ini 格式的配置文件,本次来看看 yaml,它的表达能力相比 ini 更加的强大.yaml 文件以 .yml 结尾,在介绍它的语法结构之前我们先来看看 yaml 的一些基本规则. 大小写敏感: 使用缩进表示层级关系,并且缩进只能用空格.不可以使用 tab 键.缩进的空格数目不重要,只要相同层级的元素左侧对齐即可: # 表示注释,# 到行尾的所有字符都会被忽略: yaml 支持的数据结构有以下三种: 字典:键值对的集

  • Python实现解析ini配置文件的示例详解

    目录 楔子 ini 文件 特殊格式 小结 楔子 在开发过程中,配置文件是少不了的,只不过我们有时会将 py 文件作为配置文件(config.py),然后在其它的模块中直接导入.这样做是一个好主意,不过配置文件是有专门的格式的,比如:ini, yaml, toml 等等. 而对于 Python 而言,也都有相应的库来解析相应格式的文件,下面我们来看看 ini 文件要如何解析. ini 文件 先来了解一下 ini 文件的格式: [satori] name = 古明地觉 age = 16 where 

  • Qt利用QJson实现解析数组的示例详解

    目录 前言 第一步:进行数据转换 第二步:将字符串转成QJsonDocument格式 第三步:解析json数据 前言 现在有这样一个json结构,需要使用QJson来解析,结构如下: "code": "0001", "descrip": "文本描述1详细描述", "id": "1", "title": "文本1标题", "type&quo

  • mybatis写xml时数字类型千万别用 !=‘‘(不为空串)进行判断的示例详解

    前言 最近项目内更新数据时,发现数字类型字段设置为0时不能正常的更新进数据库,我们打印了下mybatis的sql日志发现字段为0的sql没有被拼接. 样例 下面的是错误示例 ❌ <update id="update" parameterType="com.chengfengfeng.test.domain.People"> update people set <if test="age!=null and age !=''"&g

随机推荐