[英]If/Case statement in JPA Criteria Builder
I want to build up a query which search dates on different entites. 我想建立一个查询,搜索不同的entites日期。 My structure is:
我的结构是:
If a Employee has a contract I want to retrieve the contract date. 如果员工有合同我想要检索合同日期。 If an employee does not have a contract then I want to return the Employee date.
如果员工没有合同,那么我想退回员工日期。
My code so far is: 到目前为止我的代码是:
if (inputDate!= null) {
ParameterExpression<Date> exp = criteriaBuilder.parameter(Date.class, "inputDate");
criteria.add(criteriaBuilder.or(
criteriaBuilder.isNull(employee.get("contract")),
criteriaBuilder.lessThanOrEqualTo(employee.<Date>get("creationDate"), exp), criteriaBuilder.lessThanOrEqualTo((employee.join("contract").<Date>get("fromDate")), exp) ));}
This does not seem to work though. 这似乎不起作用。 I always appear to go into the isNull which I do not expect.
我似乎总是进入我不期望的isNull。
I am happy to look into this some more but I guess my question is whether this is the correct way of going about it. 我很高兴再看一下,但我想我的问题是这是否是正确的方法。 Is it?
是吗? I have seen a selectCase as well in criteriaBuilder so perhaps that may be a better solution.
我在criteriaBuilder中也看到了一个selectCase,所以也许这可能是一个更好的解决方案。
Any pointers would be greatly received. 任何指针都会受到极大的欢迎。
Thanks 谢谢
Here would be a solution, not sure if it works, but we will manage to get it work with your help :): 这将是一个解决方案,不确定它是否有效,但我们将设法让你的帮助:):
ParameterExpression<Date> inputDateExp = criteriaBuilder.parameter(Date.class, "inputDate");
Predicate employeeCreationDate = criteriaBuilder.lessThanOrEqualTo(
employee.<Date>get("creationDate"), inputDateExp);
Predicate contractStartDate = criteriaBuilder.lessThanOrEqualTo(
employee.join("contract").<Date>get("fromDate"), inputDateExp);
criteria.add(
criteriaBuilder.selectCase().when(employee.get("contract").isNull(), employeeCreationDate).otherwise(contractStartDate));
I do not understand why use "inputDate" as Expression instead of a Date? 我不明白为什么使用“inputDate”作为Expression而不是Date? Also, I suggest renaming
criteria
to c
and criteriaBuilder
to cb
, this would save space and I think it is more comfortable. 另外,我建议重命名
criteria
,以c
并criteriaBuilder
到cb
,这样可节省空间,我认为这是更舒适。
I think what you want to do is use Case<Date>
, and use Predicate
only as first argument to Case#when
. 我想你想要做的是使用
Case<Date>
,并且只使用Predicate
作为Case#when
第一个参数。 Case<Date>
is an Expression<Date>
, which is what you want to pass into CriteriaQuery#multiselect
. Case<Date>
是一个Expression<Date>
,这是你想要传递给CriteriaQuery#multiselect
。
CriteriaQuery<Employee> query = criteriaBuilder.createQuery(Employee.class);
Root<Employee> employee = query.from(Employee.class);
query.multiselect
(
criteriaBuilder.selectCase()
.when(criteriaBuilder.isNull(employee.get("contract")), employee.get("creationDate"))
.otherwise(employee.join("contract").get("fromDate"))
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.