当前位置: 首页 > 面试题库 >

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

潘俊楚
2023-03-14
问题内容

我如何知道记录在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而不进行分页,然后仅执行a
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. 好的 ,如果在数据库中执行一个额外的查询,只是找出记录位置;
  3. 好的 ,如果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

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



 类似资料:
  • 我正在研究一个问题,基本上可以归结为以下几点: 给定: null 对于这样一个位置,有什么算法的想法吗?我最终将使用java实现,但我可以使用PsuedoCode。

  • 假设我有这个类(它已经有一个id属性,但它已经由realm自动生成): 另一个里面有用户列表: 我只想对领域进行查询,以获取用户在其中的游乐设施列表。我发现了另一个这样的问题,但在这种情况下,询问者已经有了拥有整个列表的对象,他只需要在该特定对象属性列表中找到用户,但在我的情况下,我想在用户(即我已经知道)在里面。提前感谢!

  • 我在实体之间有一对多的关系。执行此JPQL查询时: 从父项选择父项加入父项。孩子在哪里。。。 当一位家长有两个孩子时,我会得到重复的记录,当一位家长有一个孩子时,我只会得到一条记录,当没有孩子时,我会得到一条记录(如果没有孩子,我就没有记录)。请注意,SQL数据库中没有重复的父数据库。 实体声明如下: 为了简洁起见,我省略了很多代码,但这应该会让你对我要做的事情有一个清晰的认识。请注意,关系是在父

  • 如何返回特定日期所在的行号? 类似这样的事情:

  • 我必须在数据库中找到所有有模式的记录。如果字段中的任何单词以特定字符串结尾。比如“is”: 所以像%is%或%is这样的简单操作是无效的。有没有什么正则表达式可以帮我做这件事?我也可以在PHP中使用LIKE%is%和filtring获得所有记录,但仍然没有任何线索如何。我有结束字符串的解决方案,但没有单词。