在JPA Criteria API中使用子查询中的ORDER BY有哪些替代方法?

Ale*_*rin 7 java sql-server hibernate jpa criteria

考虑以下两个表:

  1. Project ( id, project_name)
  2. Status ( id, id_project, status_name)

其中Status包含a所有的状态Project.

假设我们要查询最新状态名为"new"的所有项目.我想出的Sql查询是:

SELECT q.id_project FROM status q
WHERE q.status_name like 'new'
AND q.id IN (
    SELECT TOP 1 sq.id from status sq
    WHERE q.id_project = sq.id_project 
    ORDER BY sq.id DESC )
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用Criteria API复制上述查询,我​​注意到类CriteriaQuery有方法,orderBy但类Subquery没有.

我到目前为止提出的标准查询是:

CriteriaQuery<Project> q = criteriaBuilder.createQuery(Project.class);
Root<Status> qFrom       = q.from(Status.class);
Subquery<Integer> sq     = q.subquery(Integer.class);
Root<Status> sqFrom      = sq.from(Status.class);

sq.select(sqFrom.get(Status_.id))
  .where(criteriaBuilder.equal(sqFrom.get(Status_.project), qFrom.get(Status_.project))
Run Code Online (Sandbox Code Playgroud)

我被困在这里,因为Subquery sq没有任何方法可以对结果进行排序并只返回最新结果.

排序子查询以便在上述场景中获得所需结果的替代方法是什么?

Ste*_*ers 2

可以使用SELECT MAX以下命令来编写子查询SELECT TOP 1 ... ORDER BY ...

SELECT q.id_project FROM status q
WHERE q.status_name like 'new'
AND q.id = (
    SELECT MAX(sq.id) from status sq
    WHERE q.id_project = sq.id_project)
Run Code Online (Sandbox Code Playgroud)

这也会更快,因为与查找最大值相比,对所有记录进行排序要慢。正如已经发布的,它可以转换为 CriteriaQuery。

不幸的是,条件查询不支持子查询中的排序 - 请参阅以下相关答案:

/sf/ask/1368473151/#28233425 /sf/ask/388602161/#5551571

如果您确实需要ORDER BY(例如,在下面的示例中允许一定范围的值),另一种选择是使用本机查询而不是 CriteriaQuery:

Query query = entityManager.createNativeQuery(
    "SELECT bar FROM foo WHERE bar IN (SELECT TOP 10 baz FROM quux ORDER BY quuux)");
Run Code Online (Sandbox Code Playgroud)