gpt4 book ai didi

java - 使用 JPA (Hibernate) 查找包含给定记录的页面

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:50:39 25 4
gpt4 key购买 nike

我如何知道记录在 JPA 查询中的位置?

我有一个返回分页结果的服务,它或多或少地实现了一个带有这个签名的方法:

List<Record> getRecordsPage(long page, int pageSize);

当它被调用时,我只是创建一个查询并像这样配置:

TypedQuery<Record> query = entityManager.createQuery(criteriaQuery);
query.setFirstResult(page * pageSize);
query.setMaxResults(pageSize);

这对结果进行分页。这按预期工作,而且非常简单。

问题

我的另一个要求是实现一个方法来检索包含特定记录的页面。实现具有以下签名的方法:

List<Record> getRecordsPage(Record record, int pageSize);

此方法需要返回记录所在的正确页面。例如,对于 getRecordsPage(RECORD4, 2) 调用,考虑数据库状态:

1. RECORD1 
2. RECORD2
3. RECORD3
4. RECORD4
5. RECORD5

返回的页面应该是 2 包含 [RECORD3, RECORD4]

ORDER BY 参数始终被设置,并且可以是多个字段。

到目前为止的解决方案

到目前为止,我有一些解决方案:

  1. 一点也不好,但它解决了问题:

使用提供的查询,我只选择 id 而没有分页,只执行 indexOf 以找到它的位置,根据位置我可以找出记录所在的页面,然后执行使用 getRecordsPage(long page, int pageSize) 的常规流程已经实现。

  1. 不太好,因为与数据库耦合度高:

当我使用 mySQL 时,我可以执行这样的 sql:select r from (select rownum r, id from t order by x,y) z where z.id = :id,什么会返回记录的位置,我可以使用它来调用 getRecordsPage(long page, int pageSize)

好的解决方案

要求:

  1. 支持按多个字段排序;
  2. 给定一个查询,它将返回记录位置或包含记录的页面偏移量;

一个好的解决方案是:

  1. 是纯粹的 JPA;
  2. Ok 如果在数据库中执行一个额外的查询只是为了找出记录位置;
  3. Ok 如果在某些时候使用了 hibernate(因为在这种情况下 Hibernate 落后于 JPA)。

最佳答案

为了确保我理解正确:您正在显示一个 Record 并且想要显示一个包含所有记录的分页列表以预选包含您的项目的页面?

首先您必须知道关系数据库不提供数据库中记录的任何隐式排序。虽然它们似乎是从第一个到最后一个排序的,但这不是可移植和可靠的。

因此您的分页列表/网格必须按某些列明确排序。为简单起见,假设您的网格按 id 排序。您知道当前显示的记录的 ID(例如:X)。你首先需要弄清楚你的记录在你的表中的哪个位置关于这个排序顺序:

SELECT COUNT(r)
FROM Record r
WHERE r.id < :X

此查询将返回您的记录之前的记录数。现在很简单:

int page = count / pageSize

page 是从 0 开始的。

不幸的是,如果您的排序列不是唯一的,这可能无法在所有情况下都起作用。但是如果列不是唯一的,排序本身就不稳定(具有相同值的记录可能以随机顺序出现),因此考虑按额外的唯一列排序:

...
ORDER BY r.sex, r.id

在这种情况下,记录首先按性别(很多重复项)和 ID 排序。在当前记录之前计数记录的解决方案仍然有效。

关于java - 使用 JPA (Hibernate) 查找包含给定记录的页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10470273/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com