6

我想建立一个在不同实体上搜索日期的查询。我的结构是:

  • 合同有日期(不可为空)
  • 员工有日期(不可为空)
  • 员工可能有一个合同 ID(可为空)

如果员工有合同,我想检索合同日期。如果员工没有合同,那么我想返回员工日期。

到目前为止,我的代码是:

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) ));}

这似乎不起作用。我似乎总是进入我没想到的 isNull 。

我很高兴对此进行更多研究,但我想我的问题是这是否是正确的处理方式。是吗?我在标准构建器中也看到了一个 selectCase,所以也许这可能是一个更好的解决方案。

任何指针都会受到极大的欢迎。

谢谢

4

2 回答 2

9

这将是一个解决方案,不确定它是否有效,但我们将在您的帮助下设法让它工作:):

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));

我不明白为什么使用“inputDate”作为表达式而不是日期?另外,我建议重命名criteriaccriteriaBuildercb这样可以节省空间,我认为它更舒适。

于 2012-04-20T08:50:37.483 回答
3

我认为你想要做的是使用Case<Date>,并且Predicate仅作为第一个参数使用Case#whenCase<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"))
);
于 2016-09-29T16:06:29.347 回答