Fra*_*eth 8 java hibernate jpa criteria
我有一个服务返回分页结果,或多或少实现了一个带有此签名的方法:
List<Record> getRecordsPage(long page, int pageSize);
Run Code Online (Sandbox Code Playgroud)
调用它时,我只需创建一个查询并进行如下配置:
TypedQuery<Record> query = entityManager.createQuery(criteriaQuery);
query.setFirstResult(page * pageSize);
query.setMaxResults(pageSize);
Run Code Online (Sandbox Code Playgroud)
这会将结果分页.这是按预期工作的,非常简单.
我的另一个要求是实现一个方法来检索包含特定记录的页面.使用以下签名实现方法:
List<Record> getRecordsPage(Record record, int pageSize);
Run Code Online (Sandbox Code Playgroud)
此方法需要生成记录所在的右页.例如,对于getRecordsPage(RECORD4, 2)调用,考虑数据库状态:
1. RECORD1
2. RECORD2
3. RECORD3
4. RECORD4
5. RECORD5
Run Code Online (Sandbox Code Playgroud)
返回的页面应为2 [RECORD3, RECORD4].
该ORDER BY参数始终设置,可以是多个字段.
到目前为止,我有一些解决方案:
使用提供的查询我只选择没有分页的id并执行只是indexOf为了找到它的位置,并根据我可以找到记录页面的位置,然后使用getRecordsPage(long page, int pageSize)已经实现的常规过程.
当我使用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).
要求:
一个好的解决方案是:
为了确保我理解正确:您正在显示Record并希望显示所有记录的分页列表,预先选择包含您的项目的页面?
首先,您必须知道关系数据库不提供数据库中任何记录的隐式排序.虽然它们似乎从头到尾排序,但这不便携且可靠.
因此,您的分页列表/网格必须由某些列明确排序.为简单起见,请说明您的网格排序依据id.您知道当前显示的记录的ID(例如:) X.您首先需要弄清楚您的记录中关于此排序顺序的记录位置:
SELECT COUNT(r)
FROM Record r
WHERE r.id < :X
Run Code Online (Sandbox Code Playgroud)
此查询将返回记录前的记录数.现在很简单:
int page = count / pageSize
Run Code Online (Sandbox Code Playgroud)
page 是基于0的.
不幸的是,如果您的排序列不是唯一的,这可能并不适用于所有情况.但是如果列不是唯一的,则排序本身不稳定(具有相同值的记录可能以随机顺序出现),因此请考虑使用额外的唯一列进行排序:
...
ORDER BY r.sex, r.id
Run Code Online (Sandbox Code Playgroud)
在这种情况下,记录首先按sex(大量重复)和id 排序.在当前记录之前计数记录的解决方案仍然有效.
| 归档时间: |
|
| 查看次数: |
1703 次 |
| 最近记录: |