Druid 源码解读---关于SQLStatement的解读(2)

1. 什么是AST

AST是abstract syntax tree的缩写,也就是抽象语法树。和所有的Parser一样,Druid Parser会生成一个抽象语法树。 具体的过程如下:

可以通过把一个Sql语句 解析成 不同类型的对象 。从而形成 一颗树状结构 。

2. 在Druid SQL Parser中有哪些AST节点类型

在Druid中,AST节点类型主要包括SQLObject、SQLExpr、SQLStatement三种抽象型。已这3个类为基础构成了功能复杂的各种节点。

interface SQLObject {}

interface SQLExpr extends SQLObject {}

interface SQLStatement extends SQLObject {}

interface SQLTableSource extends SQLObject {}
class SQLSelect extends SQLObject {}
class SQLSelectQueryBlock extends SQLObject {}

整个AST的结构大概如下 ,以SQLSelectStatement为例:

         SQLSelectStatement

                SQLSelect   

                        SQLSelectQueryBlock 

                                      List<SQLSelectItem>-->列名

                                      SQLTableSource--->表

                                      SQLExpr-->where 语句

                                     SQLOrderBy-->排序语句

                                     SQLLimit--> limit分页操作

通过上面的结构可以形成一棵语法树

3.语法树的生成流程

        

SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType);        
  通过上面的的方法可以得到一个语法树解析器.

List<SQLStatement> stmtList = parser.parseStatementList();
通过调用解析器可以得到一棵语法树,当传入的sql是多条时,多条语句以逗号隔开,则会返回多条的list数据。

语法树生成的底层原理:

        SQLStatementParser的内部,内嵌着 SQLExprParser 对象,表达式解析的对象。

        SQLExprParser的内部,包含  Lexer lexer 分词对象。 

        Lexer对象的内部,内置了许多

        Keywords keywords = Keywords.DEFAULT_KEYWORDS; 这些关键词都是SQL语法中的关键词 ,所以我们可以大致猜测,整个处理流程 就是通过 分词器去获取SQL语句中的分词,和 分词器 内部的 keyword 做对比 ,如果 一样 则说明,该关键词的前后段 为 关键的 AST对象,需要做封装的处理 。最终形成一棵 语法树。

4 常用的SQLStatemment

最常用的Statement当然是SELECT/UPDATE/DELETE/INSERT,他们分别是

package com.alibaba.druid.sql.ast.statement;

class SQLSelectStatement implements SQLStatement {
    SQLSelect select;
}
class SQLUpdateStatement implements SQLStatement {
    SQLExprTableSource tableSource;
     List<SQLUpdateSetItem> items;
     SQLExpr where;
}
class SQLDeleteStatement implements SQLStatement {
    SQLTableSource tableSource; 
    SQLExpr where;
}
class SQLInsertStatement implements SQLStatement {
    SQLExprTableSource tableSource;
    List<SQLExpr> columns;
    SQLSelect query;
}

5. SQLSelect & SQLSelectQuery

SQLSelectStatement包含一个SQLSelect,SQLSelect包含一个SQLSelectQuery,都是组成的关系。SQLSelectQuery有主要的两个派生类,分别是SQLSelectQueryBlock和SQLUnionQuery。

class SQLSelect extends SQLObjectImpl { 
    SQLWithSubqueryClause withSubQuery;
    SQLSelectQuery query;
}

interface SQLSelectQuery extends SQLObject {}

class SQLSelectQueryBlock implements SQLSelectQuery {
    List<SQLSelectItem> selectList;
    SQLTableSource from;
    SQLExprTableSource into;
    SQLExpr where;
    SQLSelectGroupByClause groupBy;
    SQLOrderBy orderBy;
    SQLLimit limit;
}

class SQLUnionQuery implements SQLSelectQuery {
    SQLSelectQuery left;
    SQLSelectQuery right;
    SQLUnionOperator operator; // UNION/UNION_ALL/MINUS/INTERSECT
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值