加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

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

发布时间:2020-12-15 02:59:21 所属栏目:Java 来源:网络整理
导读:如何知道JPA查询中记录的位置? 我有一个服务返回分页结果,或多或少实现了一个带有此签名的方法: ListRecord getRecordsPage(long page,int pageSize); 调用它时,我只需创建一个查询并进行如下配置: TypedQueryRecord query = entityManager.createQuery(c
如何知道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参数始终设置,可以是多个字段.

解决方案直到现在

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

>一点也不好,但它解决了这个问题:

使用提供的查询,我只选择没有分页的id,只执行indexOf以找到它的位置,并根据我可以找到记录页面的位置,然后使用getRecordsPage执行常规过程(长页面,int pageSize )已经实施.

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

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

好的解决方案

要求:

>应支持多个领域的订单;
>给定一个查询,它将返回记录位置或包含记录页面的偏移量;

一个好的解决方案是:

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

解决方法

为了确保我理解正确:您正在显示一个记录,并希望显示所有记录的分页列表,预先选择包含您的项目的页面?

首先,您必须知道关系数据库不提供数据库中任何记录的隐式排序.虽然它们似乎从头到尾排序,但这不便携且可靠.

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

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

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

int page = count / pageSize

页面是从0开始的.

不幸的是,如果您的排序列不是唯一的,这可能并不适用于所有情况.但是如果列不是唯一的,则排序本身不稳定(具有相同值的记录可能以随机顺序出现),因此请考虑使用额外的唯一列进行排序:

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

在这种情况下,记录首先按性别(大量重复)和id排序.在当前记录之前计数记录的解决方案仍然有效.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读