JSqlParser如何拆分Expression

时间:2014-04-05 16:05:55

标签: java sql visitor-pattern sql-parser

假设我有格式

的表达式
a>10 and b>20 and c>30

我想获得一个表达式列表,如下所示

a>10
b>20
c>30

如果我使用表达式访问者模式,对于AndExpression访问者,我写了类似

的内容
public void visit(AndExpression andExpression) {
    andExpression.getLeftExpression().accept(this);
    andExpression.getRightExpression().accept(this);
}

但是这会递归地运行并进入每个其他访问者模式方法。当获得较小的表达式时如何停止?

如果我只使用getLeftExpressions()和getRightExpression(),我在第一次运行中得到的是左边的“a> 10”和右边的“b> 20和c> 30”。

2 个答案:

答案 0 :(得分:2)

JSqlParser以这种方式解析你的表达式:

AndExpression
   AndExpression
       a>10
       b>20
   c>30

我很想知道你使用哪个版本,如果递归确实在正确的项目中而不是左边。我使用JSqlParser 0.9-SNAPSHOT。然而,在我的 JSqlParser 版本中(我认为,因为它是一个LL解析器),在其他答案中评论建议的代码块

while(ex.getLeftExpression() != null) {
    list.add(ex.getLeftExpression()); 
    ex = ex.getRightExpression();
}

不起作用。它找到(或收集):

a > 10 AND b > 20

这是一个AndExpression并在ex = ex.getRightExpression();失败,因为右边 永远不会是AndExpression。这就是JSqlParser的工作原理。 AndExpression递归将在leftExpression

所以这是一个解决方案,并使用 JSqlParser V0.9-SNAPSHOT 围绕它进行测试,它使用递归方式访问这些AndExpressions并打印出找到的表达式。我没有将它添加到List。请原谅我。

public class JSqlParser1 {

    public static void main(String[] args) throws JSQLParserException {
        Expression expr = CCJSqlParserUtil.parseCondExpression("a>10 and b>20 and c>30");
        expr.accept(new ExpressionVisitorAdapter() {

            @Override
            public void visit(AndExpression expr) {
                if (expr.getLeftExpression() instanceof AndExpression) {
                    expr.getLeftExpression().accept(this);
                } else {
                    System.out.println(expr.getLeftExpression());
                }

                System.out.println(expr.getRightExpression());
            }

        });
    }
}

这张照片打印出来:

a > 10
b > 20
c > 30

答案 1 :(得分:1)

visit方法中,您可以为给定的Expression表达式返回And列表。所以只需返回Expression对象列表,如下所示:

public List<Expression> visit(AndExpression andExpression) {
    List<Expression> list = new ArrayList<Expression>();
    lex = andExpression.getLeftExpression();
    list.add(lex);
    rex = andExpression.getRightExpression();
    subEx1 = rex.getLeftExpression();
    subEx2 = rex.getRightExpression();
    list.add(subEx1);
    list.add(subEx2);
    return list;
}

这两个子表达式是从第一个右表达式中获得的。