Hibernate Criteria API的问题(Disjunction和Conjunction)

时间:2012-10-18 14:09:21

标签: java hibernate criteria-api

我在使用ConjunctionDisjunction时遇到问题。我的程序从ui收到任意数量的过滤元素(每个过滤元素代表Criterion),并打算将它们链接在一起作为ANDOR

例如,我可以有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基本上是enum,其中包含ORAND

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

3 个答案:

答案 0 :(得分: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没有你用连词和断开得到的括号。

答案 1 :(得分:0)

你让它变得更加困难。为什么不使用以下内容:

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

答案 2 :(得分:-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));
  }
}