如何使用JPA使用OR生成动态查询?

时间:2014-03-20 14:41:57

标签: sql hibernate java-ee jpa criteria-api

需要使用JPA生成类似的查询。它需要是动态的,因为直到运行时我才知道我会得到什么参数。

SQL我想从JPA:

从foo中选择*其中a ='A'或b ='B'或c ='C'或(x ='X'和y ='Y')

  • 如果'A','B','C','X','Y'中的任何一个将是 提供。
  • X和Y应始终使用'AND'。
  • 如果缺少其中一个输入,例如,如果没有提供C,我们应该简单地消除 - 查询变为 - “select * from foo,其中a ='A'或b ='B'或(x =' X'和y ='Y')

我使用JPA遇到的大多数示例都是在动态生成查询时使用AND运算符。或者,或者,他们使用“criteriabuilder.or(...,...,...)静态地执行它。这在我的情况下不起作用。

2 个答案:

答案 0 :(得分:1)

您可以使用CriteriaBilder#disjunction()运算符来构建要动态修改的谓词:

Integer aValue, xValue, yValue;
Predicate p = cb.disjunction();
if (aValue != null) {
    p = cb.or(p, cb.equal(foo.get("a"), aValue));
}
...
if (xValue != null && yValue != null) {
    p = cb.or(p, cb.and(cb.equal(foo.get("x"), xValue), cb.equal(foo.get("y"), yValue)));
}

或者使用谓词数组:

List<Predicate> predicateArray = new ArrayList<> ();
if (aValue != null) {
    predicateArray.add(cb.equal(foo.get("a"), aValue));
}
...
if (xValue != null && yValue != null) {
    predicateArray.add(cb.and(cb.equal(foo.get("x"), xValue), cb.equal(foo.get("y"), yValue)));
}
Predicate p = cb.or(predicateArray.toArray(new Predicate[] {})));

答案 1 :(得分:0)

您可以在String变量中编写存储该查询的查询,在该变量中您可以附加某些条件的某些部分。

一个例子:

// This part is always presents
String hql = " SELECT * FROM foo ";
String whereClause = " where ";
String whereCond = "";

if (condition on A is satisfacted) {
    whereCond += "a = 'A'";
}

if (condition on B is satisfacted) {
    if (!whereCond.equals("")) {
        whereCond += " or ";
    }
    whereCond += "b = 'B'";
}

... AND GO ON ...

At the end

String res = hql;
if (!whereCond.equals("")) {
   res += whereClause + whereCond;
}

return res;

告诉我它是否正常