Druid SQL解析原理分析(二)

概览

续上篇文章后,继续分析Drui的SQL解析原理,如果没有看上篇文章,可以先浏览下上篇文章:Druid SQL解析原理分析(一),有利于概念的连续性,更容易理解。
由于SQL解析流程过于庞大复制,本篇文章只分析访问者访问AST的主要流程。

流程分析
SQLObject 对象

SQLObject对象是Druid体系中的顶层接口,用于描述所有SQL有关的对象,比如:ASTSQLObject的一个继承类。对应访问者模式中的Element,用于接收一个访问者对象(Visitor 的具体实现类)。

访问者遍历AST语法树
  1. 使用如下方式遍历AST树
sqlStatement.accept(sqlCustomedVisitor);

2.跟踪accept方法里面后发现,accept方法是SQLObjectImpl里面的一个final方法,无法被子类重写,最后进入到了accept0方法,该方法是一个抽象的方法,子类必须重写,这里就使用到了模板方法的设计模式。
image
3.到一个实现类MySqlUpdateStatement里面去跟踪accept0的具体实现,发现这里会调用visitor.visit(this)方法,把对象自己传进去。visitor同时实现了visitor.visit(MySqlUpdateStatement mySqlUpdateStatement)方法,此时就会进入到visitor的实现里面去。
image
4. visitor访问完自身节点后,然后再去访问子节点,就如MySqlUpdateStatement实例一样。

            this.acceptChild(visitor, this.tableSource);
            this.acceptChild(visitor, this.items);
            this.acceptChild(visitor, this.where);
            this.acceptChild(visitor, this.orderBy);
            this.acceptChild(visitor, this.limit);

然后子节点又是一个SQLObject对象,再次调用accept方法,所以又回到了步骤2,以此类推,遍历完整个AST树。
image
4. 如果我们需要自定义visitor,那么必须实现 SQLASTVisitor接口,该接口是抽象访问者,定义访问者的行为规范。SQLASTVisitorAdapter类已经帮我们实现了SQLASTVisitor,所以需要自定义visitor时,可以选择继承SQLASTVisitorAdapter,然后重写特定接口即可。比如:需要通过自定义visitor获取SQL的limit RowCount数量,可以以如下方式定义visitor,当使用该visitor遍历AST树时,如果遍历到SQLLimit节点,就会调用该重写方法。

    // 自定义访问者
    class SQLCustomedVisitor extends SQLASTVisitorAdapter {

        protected boolean hasLimit = false;

        @Override
        public boolean visit(SQLLimit x) {
            System.out.println(x.getRowCount());
            hasLimit = true;
            return false;
        }

        public boolean isHasLimit() {
            return hasLimit;
        }
    }

posted on   bigstrong_code  阅读(1497)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示