初探jsqlparser
大数据处理中离不开SQL,如使用flink、查询各种数据库等场景。
用户提交sql后,系统处理往往需要知道用户提交的一些信息(查询or更新、表名、字段等),因此需要sql解析
jsqlparser介绍
jsqlparser是开源的sql解析器,是mybatis底层解析,有着较为活跃的社区支撑。地址如下:
https://github.com/JSQLParser/JSqlParser
但特定db的特色语句无法支持,如mysql的show语法;
jsqlparser把sql解析成对应的抽象语法树,并通过visitor模式对其中的数据进行访问或改写。
示例
判断sql中是否进行聚合操作(group by),并提取出表名
1.对sql进行解析
CCJSqlParserManager pm = new CCJSqlParserManager();
Statement statement = pm.parse(new StringReader(sql));
2.定义一个visitor,对语句中的group by节点进行访问判断
public class SqlElementFinder implements SelectVisitor, FromItemVisitor{
    private boolean isGroupBy;
    private List<String> tables;
    public SqlElementFinder(){
        isGroupBy = false;
        tables = new ArrayList<>();
    }
    public boolean isGroupBy() {
        return isGroupBy;
    }
    public List<String> getTables() {
        return tables;
    }
    public boolean judge(Select select){
        select.getSelectBody().accept(this);
        return isGroupBy;
    }
    @Override
    public void visit(PlainSelect plainSelect) {
        if(plainSelect.getGroupBy() != null){
            isGroupBy = true;
        }
        plainSelect.getFromItem().accept(this);
    }
    @Override
    public void visit(Table table) {
        tables.add(table.getName());
    }
    @Override
   //考虑子查询情况
    public void visit(SubSelect subSelect) {
        subSelect.getSelectBody().accept(this);
    }
}
3.判断是否为select语句,并处理
        SqlElementFinder sqlElementFinder = new SqlElementFinder();
        if(statement instanceof Select){
            System.out.println("select");
            sqlElementFinder.judge(((Select) statement));
            System.out.println(sqlElementFinder.isGroupBy());
            System.out.println(sqlElementFinder.getTables());
        } else if (statement instanceof Insert) {
            System.out.println("insert");
        } else if (statement instanceof Update){
            System.out.println("update");
        }
4.结果
//语句     
select cc from (select aa,bb,cc from tt1 where id = 1) group by cc;
//结果
select
true
[tt1]
进一步开发
考虑到jsqlparser不支持特定db的特色语句,由于jsqlparser基于javacc能力进行解析,可通过自行修改语法规则描述,并重新生成分析器,即可满足需求。
总结
jsqlparser作为开源的sql解析器,功能基本能满足我们对基本sql的解析,若需自定义语句解析,可利用javacc能力,对jsqlparser进行修改。