Druid的SQL Parser

作者: begonia_rich | 来源:发表于2018-06-01 14:23 被阅读2396次

    最近在看zebra的分库分表源码部分所使用的sql解析就是采用的SQL Parser,这里写个简单的举例方便新手理解

    简单使用举例

    public class SqlParser {
    
        public static void main(String[] args) {
            String sql = "select * from t where id=1 and name=ming group by uid limit 1,200 order by ctime";
    
            // 新建 MySQL Parser
            SQLStatementParser parser = new MySqlStatementParser(sql);
    
            // 使用Parser解析生成AST,这里SQLStatement就是AST
            SQLStatement sqlStatement = parser.parseStatement();
    
            MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
            sqlStatement.accept(visitor);
    
            System.out.println("getTables:" + visitor.getTables());
            System.out.println("getParameters:" + visitor.getParameters());
            System.out.println("getOrderByColumns:" + visitor.getOrderByColumns());
            System.out.println("getGroupByColumns:" + visitor.getGroupByColumns());
            System.out.println("---------------------------------------------------------------------------");
    
            // 使用select访问者进行select的关键信息打印
            SelectPrintVisitor selectPrintVisitor = new SelectPrintVisitor();
            sqlStatement.accept(selectPrintVisitor);
    
            System.out.println("---------------------------------------------------------------------------");
            // 最终sql输出
            StringWriter out = new StringWriter();
            TableNameVisitor outputVisitor = new TableNameVisitor(out);
            sqlStatement.accept(outputVisitor);
            System.out.println(out.toString());
        }
    
    }
    
    /**
     * 查询语句访问者
     * 
     * @author xiezhengchao
     * @since 2018/6/1 12:08
     */
    public class SelectPrintVisitor extends SQLASTVisitorAdapter {
    
        @Override
        public boolean visit(SQLSelectQueryBlock x) {
            List<SQLSelectItem> selectItemList = x.getSelectList();
            selectItemList.forEach(selectItem -> {
                System.out.println("attr:" + selectItem.getAttributes());
                System.out.println("expr:" + SQLUtils.toMySqlString(selectItem.getExpr()));
            });
    
            System.out.println("table:" + SQLUtils.toMySqlString(x.getFrom()));
            System.out.println("where:" + SQLUtils.toMySqlString(x.getWhere()));
            System.out.println("order by:" + SQLUtils.toMySqlString(x.getOrderBy().getItems().get(0)));
            System.out.println("limit:" + SQLUtils.toMySqlString(x.getLimit()));
    
            return true;
        }
    
    }
    
    /**
     * 数据库表名访问者
     * 
     * @author xiezhengchao
     * @since 2018/6/1 11:52
     */
    public class TableNameVisitor extends MySqlOutputVisitor {
    
        public TableNameVisitor(Appendable appender) {
            super(appender);
        }
    
        @Override
        public boolean visit(SQLExprTableSource x) {
            SQLName table = (SQLName) x.getExpr();
            String tableName = table.getSimpleName();
    
            // 改写tableName
            print0("new_" + tableName.toUpperCase());
    
            return true;
        }
    
    }
    
    

    这里只是简单的使用举例,对于初学者理解了通过访问者对象去获取sql的关键信息即可.具体的访问者还是要看官方文档.

    实际运行结果

    例子源码

    github:https://github.com/znyh113too/sql-parser/tree/master

    参考链接

    官方说明文档:https://github.com/alibaba/druid/wiki/SQL-Parser
    https://www.jianshu.com/p/437aa22ea3ca

    相关文章

      网友评论

        本文标题:Druid的SQL Parser

        本文链接:https://www.haomeiwen.com/subject/wuxksftx.html