package com.tongbanjie.baymax.parser.mysql.visitor; import com.alibaba.druid.sql.ast.SQLName; import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr; import com.alibaba.druid.sql.ast.expr.SQLInListExpr; import com.alibaba.druid.sql.ast.statement.SQLExprTableSource; import com.alibaba.druid.sql.ast.statement.SQLSelectStatement; import com.alibaba.druid.sql.ast.statement.SQLUpdateStatement; import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlDeleteStatement; import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor; import com.alibaba.druid.stat.TableStat; import com.alibaba.druid.stat.TableStat.Mode; import java.util.List; import java.util.Map; /** * 从ast语法中提取表名、条件、字段等的vistor * * 主要提取以下三个内容 * visitor.hasOrCondition() * visitor.getConditions() * visitor.getAliasMap() * * @Author si.dawei */ public class SqlVisitor extends MySqlSchemaStatVisitor { private boolean hasOrCondition = false; public SqlVisitor(List<Object> parameters){ setParameters(parameters); } public boolean hasOrCondition() { return hasOrCondition; } @Override public boolean visit(SQLSelectStatement x) { setAliasMap(); return true; } /** * 二元表达 * @param x * @return */ @Override public boolean visit(SQLBinaryOpExpr x) { x.getLeft().setParent(x); x.getRight().setParent(x); switch (x.getOperator()) { case Equality: // a=1 and a=2 or a=3 handleCondition(x.getLeft(), x.getOperator().name, x.getRight()); // a=b 转化为 b=a // a=1 不用转化 handleCondition(x.getRight(), x.getOperator().name, x.getLeft()); handleRelationship(x.getLeft(), x.getOperator().name, x.getRight()); break; case BooleanOr: this.hasOrCondition = true; break; default: break; } return true; } @Override public boolean visit(MySqlDeleteStatement x) { setAliasMap(); setMode(x, Mode.Delete); accept(x.getFrom()); accept(x.getUsing()); x.getTableSource().accept(this); if (x.getTableSource() instanceof SQLExprTableSource) { SQLName tableName = (SQLName) ((SQLExprTableSource) x.getTableSource()).getExpr(); String ident = tableName.toString(); setCurrentTable(x, ident); // 和父类只有这行不同 TableStat stat = this.getTableStat(ident,ident); stat.incrementDeleteCount(); } accept(x.getWhere()); accept(x.getOrderBy()); accept(x.getLimit()); return false; } @Override public void endVisit(MySqlDeleteStatement x) { } @Override public boolean visit(SQLUpdateStatement x) { setAliasMap(); setMode(x, Mode.Update); SQLName identName = x.getTableName(); if (identName != null) { String ident = identName.toString(); // String alias = x.getTableSource().getAlias(); setCurrentTable(ident); TableStat stat = getTableStat(ident); stat.incrementUpdateCount(); Map<String, String> aliasMap = getAliasMap(); aliasMap.put(ident, ident); // if(alias != null) { aliasMap.put(alias, ident); } } else { x.getTableSource().accept(this); } accept(x.getItems()); accept(x.getWhere()); return false; } }