几种基于Java的SQL解析工具的比较与调用

1.sqlparser

http://www.sqlparser.com/

优点:支持的数据库最多,除了传统数据库外还支持hive和greenplum一类比较新的数据库,调用比较方便,功能不错

缺点:收费,500$起

2、Apache Calcite

一个构建JDBC或者ODBC访问数据库的框架,通过自定义一些adapter通过sql访问任意类型的数据

优点:开源

缺点:sql解析只是一小部分功能,且只支持通用的文法树,无法对不同数据库提供本地化支持

3、druid

阿里的一个开源项目,其实是个JDBC,但是可以通过这个JDBC统计通过它提交的各种sql执行情况等信息,对提交sql进行监控统计

主页https://github.com/alibaba/druid

我们用到的SQL-Parser是它的一个组件:

https://github.com/alibaba/druid/wiki/SQL-Parser

支持数据库不算少:

public interface JdbcConstants {
    String JTDS = "jtds";
    String MOCK = "mock";
    String HSQL = "hsql";
    String DB2 = "db2";
    String DB2_DRIVER = "COM.ibm.db2.jdbc.app.DB2Driver";
    String POSTGRESQL = "postgresql";
    String SYBASE = "sybase";
    String SQL_SERVER = "sqlserver";
    String ORACLE = "oracle";
    String ORACLE_DRIVER = "oracle.jdbc.driver.OracleDriver";
    String ALI_ORACLE = "AliOracle";
    String ALI_ORACLE_DRIVER = "com.alibaba.jdbc.AlibabaDriver";
    String MYSQL = "mysql";
    String MYSQL_DRIVER = "com.mysql.jdbc.Driver";
    String MARIADB = "mariadb";
    String MARIADB_DRIVER = "org.mariadb.jdbc.Driver";
    String DERBY = "derby";
    String HBASE = "hbase";
    String HIVE = "hive";
    String H2 = "h2";
    String H2_DRIVER = "org.h2.Driver";
    String ODPS = "odps";
}

不过部分语法支持还处于开发中,比如,不支持解析postgresql的begin/commit语法,不支持group by 1, 2这种指定字段的语法。。。-_||

编译:

一开始懒得安装maven使用javac编译,结果出了一堆代码中包含的中文编码问题,花时间研究编码不如乖乖下载安装maven……-_-

在源码根目录下直接执行mvn:

mvn install -Dmaven.javadoc.skip=true -Dmaven.test.skip=true

编译后代码目录多出target子目录,里面有class和代码文件的jar包

调用很简单

package parse;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.postgresql.visitor.PGSchemaStatVisitor;
import com.alibaba.druid.stat.TableStat.*;
import com.alibaba.druid.stat.*;
import com.alibaba.druid.util.JdbcConstants;


public class testparse {

    public static void main(String[] args) {

        String sql= ""
                + "insert into tar select * from boss_table bo, ("
                    + "select a.f1, ff from emp_table a "
                    + "inner join log_table b "
                    + "on a.f2 = b.f3"
                    + ") f "
                    + "where bo.f4 = f.f5 "
                    + "group by bo.f6 , f.f7 having count(bo.f8) > 0 "
                    + "order by bo.f9, f.f10;"
                    + "select func(f) from test1; "
                    + "";
        String dbType = JdbcConstants.POSTGRESQL;

        //格式化输出
        String result = SQLUtils.format(sql, dbType);
        System.out.println(result); // 缺省大写格式
        List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, dbType);

        //解析出的独立语句的个数
        System.out.println("size is:" + stmtList.size());
        for (int i = 0; i < stmtList.size(); i++) {

            SQLStatement stmt = stmtList.get(i);

            PGSchemaStatVisitor visitor = new PGSchemaStatVisitor();
            stmt.accept(visitor);
            Map<String, String> aliasmap = visitor.getAliasMap();
            for (Iterator iterator = aliasmap.keySet().iterator(); iterator.hasNext();) {
                String key = iterator.next().toString();
                System.out.println("[ALIAS]" + key + " - " + aliasmap.get(key));
            }
            Set<Column> groupby_col = visitor.getGroupByColumns();
            //
            for (Iterator iterator = groupby_col.iterator(); iterator.hasNext();) {
                Column column = (Column) iterator.next();
                System.out.println("[GROUP]" + column.toString());
            }
            //获取表名称
            System.out.println("table names:");
            Map<Name, TableStat> tabmap = visitor.getTables();
            for (Iterator iterator = tabmap.keySet().iterator(); iterator.hasNext();) {
                Name name = (Name) iterator.next();
                System.out.println(name.toString() + " - " + tabmap.get(name).toString());
            }
            //System.out.println("Tables : " + visitor.getCurrentTable());
            //获取操作方法名称,依赖于表名称
            System.out.println("Manipulation : " + visitor.getTables());
            //获取字段名称
            System.out.println("fields : " + visitor.getColumns());
        }

    }

}

猜你喜欢

转载自blog.csdn.net/qq_21383435/article/details/81984297