【问题标题】:Use Hibernate Criteria API to return first row of each group使用 Hibernate Criteria API 返回每组的第一行
【发布时间】:2018-06-03 13:00:47
【问题描述】:

我是 Hibernate 的新手,我正在尝试编写一个条件查询来返回给定日期员工的最新状态

id  |   Status  | status_date
1   |   Active  |   1/10/2017
2   |   Active  |   1/10/2017
...
1   |   Inactive|   5/10/2017
...
1   |   Active  |   9/10/2017

所以我将向查询传递一个日期,并希望找到该日期每个员工的最新状态 预期的结果会是这样的

示例:对于日期 6/1/2017,这将是返回的数据

id  |   Status  |   Date
1   |   Inactive|   5/10/2017
2   |   Active  |   1/10/2017

我能够通过 id 添加 group by 并按状态日期以降序排列行。有没有办法只为每个组选择第一行?我尝试在 status_date 上使用 max 函数,但不起作用。

CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();
CriteriaQuery<Employee> cq = builder.createQuery(Employee);
Root<Employee> root = cq.from(Employee.class);
cq.select(root);
cq.groupBy(root.get("id"));
cq.orderBy(builder.desc(root.get("status_date")));
cq.having(builder.max(root.get("status_date")));

【问题讨论】:

标签: java hibernate oracle11g hibernate-criteria


【解决方案1】:

由于您要输出聚合,因此不要将聚合用作条件,因此不应将其放在having 子句中。您必须改为将聚合添加到选择列表中。

首先您必须创建聚合结果类(通常与您的实体类不同):

public static class StatusEntityResult {
    private String userId;
    private String status;
    private Date statusDate;
    // getter, setter, constructor with all parameters here
}

然后使用它创建一个查询作为结果:

public List<StatusEntityResult> queryStatus() throws ParseException {
    // Date condition
    Date targetDate = new SimpleDateFormat("yyyy-MM-dd").parse("2017-10-06");

    CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();

    // Use StatusEntityResult as result
    CriteriaQuery<StatusEntityResult> cq = builder.createQuery(StatusEntityResult.class);
    Root<Employee> root = cq.from(Employee.class);

    // Select `id`, `status` and `max(status_date)`
    cq.multiselect(root.get("id"), root.get("status"), builder.max(root.get("statusDate")))
            .where(builder.lessThanOrEqualTo(root.get("statusDate"), targetDate))
            .groupBy(root.get("id"))
            .orderBy(builder.desc(root.get("statusDate")));

    return this.entityManager.createQuery(cq).getResultList();
}

结果是:

旁注

根据您写的内容,您尝试使用JPA Criteria,而不是Hibernate Criteria。对于Hibernate Criteria的解决方案,可以尝试阅读@default locale的建议

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-05
    • 1970-01-01
    • 2010-12-31
    • 1970-01-01
    • 2013-06-25
    • 2021-01-17
    • 2013-09-20
    • 2016-06-22
    相关资源
    最近更新 更多