2012-10-18 28 views
1

我在使用ConjunctionDisjunction時遇到問題。我的程序從ui接收任意數量的過濾元素(每個過濾元素代表一個Criterion),並打算將它們作爲ANDOR鏈接在一起。Hibernate Criteria API的問題(分離和連接)

因此,例如,我可以有3個要素是這樣的(我代表Criterion以字母):

a OR b AND c 

我的代碼如下所示:

// ... 
    Criteria rootCriteria = createCriteria(entityClass); 
    Conjunction conjunction = Restrictions.conjunction(); 
    Disjunction disjunction = Restrictions.disjunction(); 
    boolean isFirst = true; 
    for (InternalFilterElement element : elements) { 
     if (isFirst) { 
      isFirst = false; 
      rootCriteria.add(createCriterion(element.getFilterRelation(), element.getValue())); 
     } else if (InternalFilterOperand.AND.equals(element.getInternalFilterOperand())) { 
      addCriterionToJunction(conjunction, element); 
     } else { 
      addCriterionToJunction(disjunction, element); 
     } 
    } 
    rootCriteria.add(disjunction); 
    rootCriteria.add(conjunction); 
    // ... 

我的問題是,我總是得到a AND b AND c和一些不必要的括號。

我真的很想知道的是,我使用了錯誤的工具來完成這項任務嗎?我該如何混合ANDOR運營商?

編輯

InternalFilterOperand基本上是含有ORAND

addCriterionToJunction一個enum只是增加了一個Criterion基於所述關係Junction(<,>,...)和所述值。它沒有任何副作用。

+0

什麼是'InternalFilterOperand'?你也可以分享你的'addCriterionToJunction'嗎? –

回答

6

加入conjunction/disjunction直接通過下面的代碼,你在Hibernate中混用AND和OR運算輸出:a = a或b = b AND c = c不帶括號的連接和分離可以得到。

+0

這個工作嗎?: Criterion ANDORs = null; (ANDORs == null){ if(grupo.getOperadorLogico()。equals(PesquisaFiltroOperadorLogico.AND)){ ANDORs = Restrictions.conjunction();如果(ANDORs == null){ } else { ANDORs = Restrictions.disjunction(); } } – Maxrunner

0

你讓事情變得更加困難。爲什麼不直接使用下列內容:

Junction junction = 
    InternalFilterOperand.AND.equals(element.getInternalFilterOperand()) ? 
     Restrictions.conjunction() : 
     Restrictions.disjunction(); 
for (InternalFilterElement element : elements) { 
    addCriterionToJunction(junction, element); 
} 
rootCriteria.add(junction); 
+1

我已經試過了。也不起作用。每個InternalFilterElement包含一個OR或一個AND,因此我無法決定在循環外使用哪一個。 –

-1

我靠近相信InternalFilterOperand未在elements正確設置爲一切看起來正常。

請在您的循環中打印/調試element.getInternalFilterOperand()值作爲驗證和糾正的第一條語句。

編輯:在下面的

Criteria rootCriteria = createCriteria(entityClass); 
    rootCriteria.add(Restrictions.or(
      Restrictions.eq("a","a"), 
      Restrictions.and(
        Restrictions.eq("b","b"), 
        Restrictions.eq("c","c") 
      ) 
    )); 

這個例子的結果:嘗試在rootCriteria

for (InternalFilterElement element : elements) { 
    if (isFirst) { 
     isFirst = false; 
     rootCriteria.add(
       createCriterion(element.getFilterRelation(), element.getValue())); 
    }else if (InternalFilterOperand.AND.equals(element.getInternalFilterOperand())){ 
     //add debugg/sys out: adding conjunction 
     System.out.println("adding conjunction"); 
     rootCriteria.add(Restrictions.conjunction().add(element)); 
    } else { 
     //add debugg/sys out: adding disjunction 
     System.out.println("adding disjunction"); 
     rootCriteria.add(Restrictions.disjunction().add(element)); 
    } 
} 
+0

我在我的'InternalFilterElement'中覆蓋了toString(),並且如果我通過'elements'讀取它打印出如下的內容:「null foo = bar and wom = bat or baz = bar」。第一個元素不包含操作數,但沒關係。 –

+0

幫我一個忙,把它們作爲第一個語句添加到'for'循環中並共享輸出。 '的System.out.println(InternalFilterOperand.AND);的System.out.println(元素。getInternalFilterOperand()); System.out.println(InternalFilterOperand.AND.equals(element.getInternalFilterOperand()));' –

+0

我已經在我以前的評論中分享過。我真正想知道的是:「我怎樣才能混合AND和OR操作符?」 –