mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
Page:
Druid_SQL_AST
Pages
Benchmark_aliyun
Contributors
DBCP迁移
Druid Change Log
DruidDataSource
DruidDataSource动态配置
DruidDataSource统计数据日志输出格式
DruidDataSource配置
DruidDataSource配置属性列表
Druid_SQL_AST
Druid中使用log4j2进行日志输出
Druid连接池介绍
Druid锁的公平模式问题
EvalVisitor
ExceptionSorter_cn
ExportParameterVisitor_demo_cn
FAQ
Home
JDBC_Properties
KeepAlive_cn
MySQL SQL Parser
OnFatalErrorMaxActive
Oracle Driver Internal API
Oracle数据库下PreparedStatementCache内存问题解决方案
ParameterizedOutputVisitor
SQL Parser
SQL_Format
SQL_Parser_Demo_visitor
SQL_Parser_Parameterize
SQL_RemoveCondition_demo
SQL_Schema_Repository
SQL格式化
SchemaStatVisitor
SchemaStatVisitor_RelationShip
StatFilter_Items
TableMapping_cn
Use_PageUtils
WallFilter 拦截规则
druid monitor设计
getCreateTableScript
large_amount_datasource_cn
linux benchmark
xxxxx
使用ConfigFilter
使用EncodingConvertFilter
使用Spring4的JavaConfig整合Druid Hibernate4.3
关于BoneCP
内置Filter的别名
分库分表
各种数据库连接池对比
各种连接池性能对比测试
如何修改SQL添加条件
如何参与
如何在Spring Boot中配置数据库密码加密?
如何捐赠
定时输出统计信息到日志中
常见问题
怎么保存Druid的监控记录
数据库多数据源
新手指南
注解方式配置监控
简介_WallFilter
设计_动态修改maxActive支持
贡献者者代码编写及提交规范
连接泄漏监测
配置 wallfilter
配置_DruidDataSource参考配置
配置_Druid和Spring关联监控配置
配置_Filter配置
配置_JNDI_Jetty
配置_JNDI_Tomcat
配置_LogFilter
配置_StatFilter
配置_StatViewFilter
配置_StatViewServlet配置
配置_配置WebStatFilter
配置druid内置的log实现
首页
Clone
Table of Contents
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
1. 什么是AST
AST是abstract syntax tree的缩写,也就是抽象语法树。和所有的Parser一样,Druid Parser会生成一个抽象语法树。
2. 在Druid SQL Parser中有哪些AST节点类型
在Druid中,AST节点类型主要包括SQLObject、SQLExpr、SQLStatement三种抽象类型。
package com.alibaba.druid.sql.ast;
interface SQLObject {}
interface SQLExpr extends SQLObject {}
interface SQLStatement extends SQLObject {}
interface SQLTableSource extends SQLObject {}
class SQLSelect extends SQLObject {}
class SQLSelectQueryBlock extends SQLObject {}
2.1. 常用的SQLExpr有哪些
package com.alibaba.druid.sql.ast.expr;
// SQLName是一种的SQLExpr的Expr,包括SQLIdentifierExpr、SQLPropertyExpr等
public interface SQLName extends SQLExpr {}
// 例如 ID = 3 这里的ID是一个SQLIdentifierExpr
class SQLIdentifierExpr implements SQLExpr, SQLName {
String name;
}
// 例如 A.ID = 3 这里的A.ID是一个SQLPropertyExpr
class SQLPropertyExpr implements SQLExpr, SQLName {
SQLExpr owner;
String name;
}
// 例如 ID = 3 这是一个SQLBinaryOpExpr
// left是ID (SQLIdentifierExpr)
// right是3 (SQLIntegerExpr)
class SQLBinaryOpExpr implements SQLExpr {
SQLExpr left;
SQLExpr right;
SQLBinaryOperator operator;
}
// 例如 select * from where id = ?,这里的?是一个SQLVariantRefExpr,name是'?'
class SQLVariantRefExpr extends SQLExprImpl {
String name;
}
// 例如 ID = 3 这里的3是一个SQLIntegerExpr
public class SQLIntegerExpr extends SQLNumericLiteralExpr implements SQLValuableExpr {
Number number;
// 所有实现了SQLValuableExpr接口的SQLExpr都可以直接调用这个方法求值
@Override
public Object getValue() {
return this.number;
}
}
// 例如 NAME = 'jobs' 这里的'jobs'是一个SQLCharExpr
public class SQLCharExpr extends SQLTextLiteralExpr implements SQLValuableExpr{
String text;
}
2.2. 常用的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;
}
2.3. SQLTableSource
常见的SQLTableSource包括SQLExprTableSource、SQLJoinTableSource、SQLSubqueryTableSource、SQLWithSubqueryClause.Entry
class SQLTableSourceImpl extends SQLObjectImpl implements SQLTableSource {
String alias;
}
// 例如 select * from emp where i = 3,这里的from emp是一个SQLExprTableSource
// 其中expr是一个name=emp的SQLIdentifierExpr
class SQLExprTableSource extends SQLTableSourceImpl {
SQLExpr expr;
}
// 例如 select * from emp e inner join org o on e.org_id = o.id
// 其中left 'emp e' 是一个SQLExprTableSource,right 'org o'也是一个SQLExprTableSource
// condition 'e.org_id = o.id'是一个SQLBinaryOpExpr
class SQLJoinTableSource extends SQLTableSourceImpl {
SQLTableSource left;
SQLTableSource right;
JoinType joinType; // INNER_JOIN/CROSS_JOIN/LEFT_OUTER_JOIN/RIGHT_OUTER_JOIN/...
SQLExpr condition;
}
// 例如 select * from (select * from temp) a,这里第一层from(...)是一个SQLSubqueryTableSource
SQLSubqueryTableSource extends SQLTableSourceImpl {
SQLSelect select;
}
/*
例如
WITH RECURSIVE ancestors AS (
SELECT *
FROM org
UNION
SELECT f.*
FROM org f, ancestors a
WHERE f.id = a.parent_id
)
SELECT *
FROM ancestors;
这里的ancestors AS (...) 是一个SQLWithSubqueryClause.Entry
*/
class SQLWithSubqueryClause {
static class Entry extends SQLTableSourceImpl {
SQLSelect subQuery;
}
}
2.4. 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
}
2.5. SQLCreateTableStatement
建表语句包含了一系列方法,用于方便各种操作
public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLStatement, SQLCreateStatement {
SQLExprTableSource tableSource;
List<SQLTableElement> tableElementList;
Select select;
// 忽略大小写的查找SQLCreateTableStatement中的SQLColumnDefinition
public SQLColumnDefinition findColumn(String columName) {}
// 忽略大小写的查找SQLCreateTableStatement中的column关联的索引
public SQLTableElement findIndex(String columnName) {}
// 是否外键依赖另外一个表
public boolean isReferenced(String tableName) {}
}
3. 怎样产生AST
3.1. 通过SQLUtils产生List<SQLStatement>
import com.alibaba.druid.util.JdbcConstants;
String dbType = JdbcConstants.MYSQL;
List<SQLStatement> statementList = SQLUtils.parseStatements(sql, dbType);
3.2. 通过SQLUtils产生SQLExpr
String dbType = JdbcConstants.MYSQL;
SQLExpr expr = SQLUtils.toSQLExpr("id=3", dbType);
4. 怎样打印AST节点
4.1. 通过SQLUtils工具类打印节点
package com.alibaba.druid.sql;
public class SQLUtils {
// 可以将SQLExpr/SQLStatement打印为String类型
static String toSQLString(SQLObject sqlObj, String dbType);
// 可以将一个<SQLStatement>打印为String类型
static String toSQLString(List<SQLStatement> statementList, String dbType);
}
5. 如何自定义遍历AST节点
所有的AST节点都支持Visitor模式,需要自定义遍历逻辑,可以实现相应的ASTVisitorAdapter派生类,比如 https://github.com/alibaba/druid/wiki/SQL_Parser_Demo_visitor