1. 什么是AST

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

在Druid中,AST节点类型主要包括SQLObject、SQLExpr、SQLStatement三种抽象类型。

  1. package com.alibaba.druid.sql.ast.expr;
  2.  
  3. // SQLName是一种的SQLExpr的Expr,包括SQLIdentifierExpr、SQLPropertyExpr等
  4. public interface SQLName extends SQLExpr {}
  5.  
  6. // 例如 ID = 3 这里的ID是一个SQLIdentifierExpr
  7. class SQLIdentifierExpr implements SQLExpr, SQLName {
  8. String name;
  9. }
  10.  
  11. // 例如 A.ID = 3 这里的A.ID是一个SQLPropertyExpr
  12. class SQLPropertyExpr implements SQLExpr, SQLName {
  13. SQLExpr owner;
  14. String name;
  15. }
  16.  
  17. // 例如 ID = 3 这是一个SQLBinaryOpExpr
  18. // left是ID (SQLIdentifierExpr)
  19. // right是3 (SQLIntegerExpr)
  20. class SQLBinaryOpExpr implements SQLExpr {
  21. SQLExpr left;
  22. SQLExpr right;
  23. SQLBinaryOperator operator;
  24. }
  25.  
  26. // 例如 select * from where id = ?,这里的?是一个SQLVariantRefExpr,name是'?'
  27. class SQLVariantRefExpr extends SQLExprImpl {
  28. String name;
  29.  
  30. // 例如 ID = 3 这里的3是一个SQLIntegerExpr
  31. public class SQLIntegerExpr extends SQLNumericLiteralExpr implements SQLValuableExpr {
  32. Number number;
  33.  
  34. // 所有实现了SQLValuableExpr接口的SQLExpr都可以直接调用这个方法求值
  35. @Override
  36. public Object getValue() {
  37. return this.number;
  38. }
  39. }
  40.  
  41. // 例如 NAME = 'jobs' 这里的'jobs'是一个SQLCharExpr
  42. public class SQLCharExpr extends SQLTextLiteralExpr implements SQLValuableExpr{
  43. String text;
  44. }

2.2. 常用的SQLStatemment

  1. package com.alibaba.druid.sql.ast.statement;
  2.  
  3. class SQLSelectStatement implements SQLStatement {
  4. SQLSelect select;
  5. }
  6. class SQLUpdateStatement implements SQLStatement {
  7. SQLExprTableSource tableSource;
  8. List<SQLUpdateSetItem> items;
  9. SQLExpr where;
  10. }
  11. class SQLDeleteStatement implements SQLStatement {
  12. SQLTableSource tableSource;
  13. SQLExpr where;
  14. }
  15. class SQLInsertStatement implements SQLStatement {
  16. SQLExprTableSource tableSource;
  17. List<SQLExpr> columns;
  18. SQLSelect query;
  19. }

常见的SQLTableSource包括SQLExprTableSource、SQLJoinTableSource、SQLSubqueryTableSource、SQLWithSubqueryClause.Entry

2.4. SQLSelect & SQLSelectQuery

  1. class SQLSelect extends SQLObjectImpl {
  2. SQLWithSubqueryClause withSubQuery;
  3. SQLSelectQuery query;
  4. }
  5.  
  6. interface SQLSelectQuery extends SQLObject {}
  7. class SQLSelectQueryBlock implements SQLSelectQuery {
  8. List<SQLSelectItem> selectList;
  9. SQLTableSource from;
  10. SQLExprTableSource into;
  11. SQLExpr where;
  12. SQLSelectGroupByClause groupBy;
  13. SQLOrderBy orderBy;
  14. SQLLimit limit;
  15. }
  16.  
  17. class SQLUnionQuery implements SQLSelectQuery {
  18. SQLSelectQuery left;
  19. SQLSelectQuery right;
  20. SQLUnionOperator operator; // UNION/UNION_ALL/MINUS/INTERSECT
  21. }

建表语句包含了一系列方法,用于方便各种操作

  1. public class SQLCreateTableStatement extends SQLStatementImpl implements SQLDDLStatement, SQLCreateStatement {
  2. SQLExprTableSource tableSource;
  3. List<SQLTableElement> tableElementList;
  4. Select select;
  5.  
  6. // 忽略大小写的查找SQLCreateTableStatement中的SQLColumnDefinition
  7. public SQLColumnDefinition findColumn(String columName) {}
  8.  
  9. // 忽略大小写的查找SQLCreateTableStatement中的column关联的索引
  10. public SQLTableElement findIndex(String columnName) {}
  11.  
  12. // 是否外键依赖另外一个表
  13. public boolean isReferenced(String tableName) {}
  14. }

3. 怎样产生AST

3.1. 通过SQLUtils产生List<SQLStatement>

  1. String dbType = JdbcConstants.MYSQL;
  2. SQLExpr expr = SQLUtils.toSQLExpr("id=3", dbType);

4. 怎样打印AST节点

4.1. 通过SQLUtils工具类打印节点

  1. package com.alibaba.druid.sql;
  2.  
  3. public class SQLUtils {
  4. // 可以将SQLExpr/SQLStatement打印为String类型
  5. static String toSQLString(SQLObject sqlObj, String dbType);
  6.  
  7. // 可以将一个&lt;SQLStatement&gt;打印为String类型
  8. static String toSQLString(List<SQLStatement> statementList, String dbType);
  9. }

5. 如何自定义遍历AST节点

6. 相关阅读