2

我在使用Conjunctions 和Disjunctions 时遇到问题。我的程序从 ui 接收任意数量的过滤器元素(每个表示 a Criterion),并打算将它们链接在一起作为ANDor OR

因此,例如,我可以有 3 个这样的元素(我Criterion用字母表示 a):

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基本上是一个enum包含ORAND

addCriterionToJunction只需根据关系 (<, >, ...) 和值添加 aCriterion即可。Junction它没有任何副作用。

4

3 回答 3

6

通过使用以下代码,您可以在 Hibernate 中混合使用 AND 和 OR 运算符:

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

此示例产生以下输出:a=a OR b=b AND c=c 不带括号,您会得到合取和析取。

于 2012-12-11T12:11:39.557 回答
0

你让它变得比必要的更难。为什么不只使用以下内容:

Junction junction = 
    InternalFilterOperand.AND.equals(element.getInternalFilterOperand()) ? 
        Restrictions.conjunction() : 
        Restrictions.disjunction();
for (InternalFilterElement element : elements) {
    addCriterionToJunction(junction, element);
}
rootCriteria.add(junction);
于 2012-10-18T14:24:00.497 回答
-1

我几乎相信InternalFilterOperand您的设置不正确,elements因为其他一切看起来都正确。

请打印/调试element.getInternalFilterOperand()循环中的值作为第一个语句以验证和更正。

编辑:尝试conjunction/disjunction直接在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));
  }
}
于 2012-10-18T14:47:01.650 回答