2017-10-17 24 views
0

JSqlParserを使用してSQL where句を完全に簡潔に解析したいと思います。これは、出力を生成しますので、JSqlParserでwhere句を完全に解析する

String whereClause = "a=3 AND b=4 AND c=5"; 
Expression expr = CCJSqlParserUtil.parseCondExpression(whereClause); 
expr.accept(new ExpressionVisitorAdapter() { 

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

のような個々の条件文の中にそれを解析するのは簡単です:私が欲しいもの

a=3 
b=4 
c=5 

はなるように側、オペレータや個々の表現の右側を左に取得することです私はいくつかの既存のフィルターオブジェクトに値を入れることができます。私はあなたがそうのようなオペレータの種類ごとに訪問の機能を無効にすることができます知っている

expr.accept(new ExpressionVisitorAdapter() { 

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

});あなたにこの出力を取得します

a 
= 
3 
a=3 
b 
= 
4 
b=4 
c 
= 
5 
c=5 

をしかし、それだけで一緒にAND演算されEqualsTo条件文をカバーしています。ご覧のとおり、すべての論理演算子に対してif文を作成し、各比較演算子のvisit()関数をオーバーライドする必要があります。これを行う簡単な方法はありますか?

答えて

0

ExpressionVisitorAdapterを使用して、それらの式のすべてのために呼び出され

protected void visitBinaryExpression(BinaryExpression expr) 

を上書きすることができます。

操作はバイナリ表現です。だからあなたはinstanceof ComparisonOperatorでタイプをチェックする必要があります。これは+ *のような操作ではなく、すべてのコンパレータを処理します。

これはそれを行う必要があります。私はANDの訪問を取り除き、whereClauseをいくつかの式で拡張しました。

String whereClause = "a=3 AND b=4 AND c=5 AND d>5 AND x<10"; 
    Expression expr = CCJSqlParserUtil.parseCondExpression(whereClause); 
    expr.accept(new ExpressionVisitorAdapter() { 

     @Override 
     protected void visitBinaryExpression(BinaryExpression expr) { 
      if (expr instanceof ComparisonOperator) { 
       System.out.println("left=" + expr.getLeftExpression() + " op=" + expr.getStringExpression() + " right=" + expr.getRightExpression()); 
      } 

      super.visitBinaryExpression(expr); 
     } 
    }); 

この出力:より多くの開発およびヘルプwumpzから」と答えた後

left=a op== right=3 
left=b op== right=4 
left=c op== right=5 
left=d op=> right=5 
left=x op=< right=10 
+0

おかげでの入力文字列の次の出力を生成します答えのために。私がそれを上告することができれば私はそれを望む。それは大きな助けとなった。しかし、あなたのソリューションはwhere節を完全に解析しません。それは比較自体を示すだけです。私は来たより完全な答えを投稿します。 – codering

+0

私は私のソリューションがあなたが達成したいと思ったものだと思った。誤解。だから私はあなたに投票した。 :) – wumpz

1

、私は解決策を持っています。関数parseWhereClauseToFilter()は、論理演算子と比較を使ってwhere節を解析します。私はBETWEENやINなどの演算子をテストしていませんが、その解決策は似ていると思います。私も助けになったので、hereの質問を見つけました。

public static void parseWhereClauseToFilter(String whereClause){ 

    try { 
     Expression expr = CCJSqlParserUtil.parseCondExpression(whereClause); 
     FilterExpressionVisitorAdapter adapter = new FilterExpressionVisitorAdapter(); 
     expr.accept(adapter); 

    } catch (JSQLParserException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 
} 
public class FilterExpressionVisitorAdapter extends ExpressionVisitorAdapter{ 
    int depth = 0; 
    public void processLogicalExpression(BinaryExpression expr, String logic){ 
     System.out.println(StringUtils.repeat("-", depth) + logic); 

     depth++; 
     expr.getLeftExpression().accept(this); 
     expr.getRightExpression().accept(this); 
     if( depth != 0){ 
      depth--; 
     } 
    } 

    @Override 
    protected void visitBinaryExpression(BinaryExpression expr) { 
     if (expr instanceof ComparisonOperator) { 
      System.out.println(StringUtils.repeat("-", depth) + 
       "left=" + expr.getLeftExpression() + 
       " op=" + expr.getStringExpression() + 
       " right=" + expr.getRightExpression()); 
     } 
     super.visitBinaryExpression(expr); 
    } 

    @Override 
    public void visit(AndExpression expr) { 
     processLogicalExpression(expr, "AND"); 

    } 
    @Override 
    public void visit(OrExpression expr) { 
     processLogicalExpression(expr, "OR"); 
    } 
    @Override 
    public void visit(Parenthesis parenthesis) { 
     parenthesis.getExpression().accept(this); 
    } 

} 

以下のコードは、 "A = 3および(b = 4、およびc = 5)およびd> 5"

AND 
-AND 
--left=a op== right=3 
--AND 
---left=b op== right=4 
---left=c op== right=5 
-left=d op=> right=5