1、Druid解析引擎概要

Druid SQL 解析引擎主要分为三个部分,AST抽象语法树,词法解析,语法解析。

AST抽象语法树,语法解析的结果,由众多AST语法对象组成一颗树,而词法分析就是解析出一个一个关键字,作为语法解析的输入。

Druid SQL解析引擎整体介绍,推荐一篇文章:http://www.tuicool.com/articles/NNJNbmF

 

故本节重点认识一下Druid解析引擎中抽象语法树中对象。

整颗ast语法对象,大体可以分为如下三类,表达式(expr,包括运算符)、语句级(statement)、其他(基础类,比如hint)。

2、表达式(Expr,运算符)

druid关于表达式的常用对象如图所示:

图片如果不清晰,建议下载原图浏览。

基于如下SQL举例说明如下对象:

select a.id,a.name,(select count(1) from acc_b b where b.user_id=a.id) as num from acc_user a 
  • SQLExpr 表达式根接口对象
  • SQLPropertyExpr 查询字段列表,比如上面查询列表中的 a.id ,a.name 就是用一个SQLPropertyExpr表示
  • SQLIdentifierExpr 一般表示表名或别名,还是上面的a.id,整体是一个SQLPropertyExpr,但SQLPropertyExpr由owner与name组成,其中name为id,而表的别名由owner来表示,也就是一个SQLIdentiferExpr,如图所示:
  • SQLAllColumnExpr 查询字段(*)的表示符
  • SQLLiteralExpr 字面量表示,其子类如下:
  • SQLIntegerExpr 整数型字面量表达式,比如 where a.id = 1 ,其中1就是用SQLIntegerExpr来表示。下面的类似
  • SQLBooleanExpr
  • SQLNumericLiteralExpr
  • SQLCharExpr
  • SQLDateExpr
  • SQLTextLiteralExpr
  • SQLTimestampExpr
  • SQLAllExpr、SQLSomeExpr、SQLAnyExpr 运算符 all,some、any。
  • SQLQueryExpr 出现在select 查询列表中,是查询的情况,如下:【select a.id,a.name,(select count(1) from acc_b b where b.user_id=a.id) as num from acc_user a 】
  • SQLVariantRefExpr 预编译,占位符,比如?或序号索引

SQLBetweenExpr  

  • 1、beginExpr,endExpr是字面值表达式,例如SQLIntegerExpr 
  • 2、testExpr,SQLPropertyExpr,例如a.num(字段名)

SQLBinaryOpExpr 二维运算符表,比如 a.name = 1,这个表达式,左边是a.name(SQLPropertyExpr),右边是SQLIntegerExpr(字面量表达式),而中间是运算符,等于。


3、语句(statement)

每一条SQL语句都会对应一个Statement类,比如创建数据库,创建表,删除修改表,查询,更新,删除,插入等语句,本节主要讲解常用的语句进行讲解。

图片如果不清晰,建议下载原图浏览。
SQLAlterDatabaseStatement、SQLCreateDatabaseStatement、SQLDropDatabaseStatement 创建数据库,修改数据库、创建表,创建索引,增加字段等,都会对应一个statement,在这里就不详细展开,根据类名基本就能知道改类对应什么SQL语句。

  • SQLConstraint : SQL约束
  • SQLIfStatement:IF语句,包含ElseIf,Else
  • SQLLoopStatement : sql循环语句。
  • SQLBlockStatement: SQL语句块语句

SQLCallStatement:存储过程描述, 包括存储过程名称,所有参数(包括入参、出参),出参。(SQLVariantRefExpr)。
接下来重点描述,查询语句,插入语句,更新语句,删除语句。


2.1 SQLSelectStatement

查询语句,包含两个属性,一个是SQLSelect对象,一个是List<CommentHint>。
SQLSelect来表示一个select查询的各个部分,分为withSubQuery、查询语句主体部分(SQLSelectQuery)、排序(SQLOrderBy)和 List<SQLHint>。

查询主体部分SQLSelectQuery包含如下实现类:SQLUnionQuery、SQLSelectQueryBlock、SQLUnionQuery的left,right属性又是一个SQLSelectQuery,不难看出,最终的查询主体部分会落到SQLSelectQueryBlock上。

查询部分(SQLSelectQueryBlock)包括如下组成部分:

  • 查询字段列表 List<SQLSelectItem>,如果是 select id,name 这种字段列表,则表示为SQLIdentifierExpr,如果是select a.id,a.name则表示为SQLPropertyExpr。
  • from 属性,类型为SQLTableSource,SQLTableSource有如下几个实现类,SQLExprTableSource、SQLJoinTableSource、SQLSubqueryTableSource、SQLUnionQueryTableSource。       
    a、SQLExprTableSource:from 后面接简单的表名,例如 select a.id,a.name from acc_user a。

    b、SQLJoinTableSource : from 后面的表使用了连接操作,比如select a.id,a.name from acc_user a left join acc_account b on b.user_id=a.id and b.id=a.id, 该对象拥有 SQLTableSource left,right(典型的二叉树结构),joinType属性表明连接的类型。condition,用一个SQLExpr来表示,大家或许会想,如果有两个连怎么办,只用一个SQLExpr如何表示多个条件,其实是通过SQLBinaryOpExpr这个二元操作符来表示的,SQLBinaryOpExpr两个类型为SQLExpr的left,right属性,然后一个运算符。

    c、SQLSubqueryTableSource:子查询表,例如 select * from (select a.id,a.name from acc_user a) tmp;该对象内部再持有一个SQLSelect对象。

     d、SQLUnionQueryTableSource,union表,,内部持有一个SQLUnionQuery对象。

  • into 属性,类型为SQLExprTableSouce,into关键字后接一个普通的表。
  • where属性,类型为SQLExpr,这里的原理与join 的 on 条件类似,如果有多个条件,会用SQLBinaryOpExpr对象来表示(二元运算符),通过left.right组织成一颗树。
  • groupBy属性 ,SQLSelectGroupByClause,group by a.name,a.id ,首先会有多个a.name,用一个List<SQLExpr> items表示,用一个SQLExpr表示having。
  • 6)orderBy属性,SQLOrderBy,就是用List<SQLSelectOrderByItem>,来表示(order by a.id desc,a.create_time desc)
  • limit属性,类型SQLLimit,limit 1,5, (limitoffset,rowCount)就是两个属性,offSet, rowCount。

2.2 SQLInsertStatement

SQLInsertStatement继承自SQLInsertInfo类,MySqlInsertStatement继承SQLInsertStatement。

insert 语句的基本信息,封装在SQLInsertInfo,主要有如下属性:

  • SQLExprTableSource  tableSource,插入目的表名
  • List<SQLExpr> columns,插入字段列表
  • SQLSelect  query,select 查询语句
  • List<ValuesClause> valuesList,valeus 列表,与query二选一存在,每一个ValuesClause为一个值列表,想象一下该语句 insert into es_user(id,name) values (1,2),(3,4);

2.3 SQLUpdateStatement

对应更新SQL语句,属性介绍如下:

  • List<SQLUpdateSetItem> items, set 字段列表,set a.id=1,a.name="a",一个SQLUpdateSetItem由一个SQLExpr column和SQLExpr value来表示。
  • SQLTableSourceTable tableSouce,更新的表名
  • SQLExpr   where,where条件

2.4 SQLDeleteStatement

删除SQL语句,主要属性如下:

  • SQLTableSource tableSource,操作的表名、
  • SQLExpr where,where 条件。

 

欢迎加笔者微信号(dingwpmz),加群探讨,笔者优质专栏目录:

1、源码分析RocketMQ专栏(40篇+)
2、源码分析Sentinel专栏(12篇+)
3、源码分析Dubbo专栏(28篇+)
4、源码分析Mybatis专栏
5、源码分析Netty专栏(18篇+)
6、源码分析JUC专栏
7、源码分析Elasticjob专栏
8、Elasticsearch专栏
9、源码分析Mycat专栏

GitHub 加速计划 / druid / druid
27.83 K
8.56 K
下载
阿里云计算平台DataWorks(https://help.aliyun.com/document_detail/137663.html) 团队出品,为监控而生的数据库连接池
最近提交(Master分支:3 个月前 )
f060c270 - 13 天前
1613a765 * Improve gaussdb ddl parser * fix temp table 15 天前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐