天天看点

什么是SQL解析

这里给出使用的druid坐标

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>
           

注意:druid不同版本结果可能会有细微差异。

然后以Postgres数据库的语法进行解析。其实解析大致上都相同,数据库的差异对解析影响不是很大,最重要的还是思想。

要使用druid进行SQL解析,你需要先明白SQL的执行顺序,SQL大致的执行顺序

FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY
           

当然这也只是个大致的顺序,具体细节还需自己去探索。

我们先用最简单的SQL来看看什么是SQL解析。

public static void main(String[] args) {
        String sql = "select * from t";
        List<SQLStatement> sqlStatements = SQLUtils.parseStatements(sql, JdbcConstants.POSTGRESQL);
        SQLStatement sqlStatement = sqlStatements.get(0);
        System.out.println(sqlStatement);
    }
           

这里的sqlStatements对象我们暂时不用管它是什么,主要看sqlStatement对象,这里面封装了SQL语句的全部信息。

现在我们使用debug查看sqlStatement对象里面到底是什么如图

什么是SQL解析

其实这里的sqlStatement就是大家说的AST(抽象语法树),这里面没有什么重要的信息,就一个dbType,可以看到数据库类型。然后我们继续看这个select

什么是SQL解析

看上去也没有什么,我们继续点开query

什么是SQL解析

这里面看上去信息就很全,这里面的各种关键字都是用来存放SQL语句中的信息的,由于刚才SQL中只有select和from信息,所以我们可以看到其他信息比如order by 都是 null,我们在点看 selectList 和 from

什么是SQL解析

可以看到我们的select * 和from t中的信息都被存放了进去。

由此我们就可以知道,druid解析,实际上就是把SQL语句中的信息全部都解析出来放在这个sqlStatement中

然后我们只需去解析这个sqlStatement对象就可以了,至于sqlStatement对象怎么解析,后面的博客会说到,这里只是入门。

下面我们再来解析个复杂的SQL

public static void main(String[] args) {
        String sql = "select seq,remark,grade from student where 1=1 group by grade order by seq";
        List<SQLStatement> sqlStatements = SQLUtils.parseStatements(sql, JdbcConstants.POSTGRESQL);
        SQLStatement sqlStatement = sqlStatements.get(0);
        System.out.println(sqlStatement);
    }
           

同样的我们还是debug看sqlStatement对象,这次我们直接看query对象

什么是SQL解析

怎么样,是不是我们SQL的信息这里面都有,我们暂时先不用管这些信息的数据结构是什么样的,只用看到这些信息都有就行。

我们先点开这个orderBy 看看里面是什么

什么是SQL解析

orderBy对象里面有个items是一个List对象,这里面存放你order by 后面的字段,一个字段就是一个items的元素

再看一下这个groupBy

什么是SQL解析

它和orderBy类似也是一个group by后面一个字段就是一个items对象

不同的是它还有个having对象,这个在你的SQL有having关键字时就会填充进去。

其实还有其他的解析方式,比如visitor,但我觉得没有直接解析这个statement对象来的直接。

就比如这样

public static void main(String[] args) {
        String sql = "with t as (select * from t) select seq,remark,grade from student where 1=1 group by grade order by seq";
        List<SQLStatement> sqlStatements = SQLUtils.parseStatements(sql, JdbcConstants.POSTGRESQL);
        SQLStatement sqlStatement = sqlStatements.get(0);
        PGSchemaStatVisitor visitor = new PGSchemaStatVisitor();
        sqlStatement.accept(visitor);
        System.out.println(sqlStatement);
    }
           

这样你就可以debug查看visitor,有兴趣可以看看。

其实SQL解析在很多公司都会用到,但是发现博客很少,大多都是个入门,刚好我使用到了,经过4个月的开发,算是有了一些经验,想写在这留个笔记,方便以后回忆,也希望给要入手SQL解析的人有个帮助。