Spring Pagination 中的偏移量计算

Posted

技术标签:

【中文标题】Spring Pagination 中的偏移量计算【英文标题】:Offset calculation in Spring Pagination 【发布时间】:2018-03-31 11:07:09 【问题描述】:

我有一个分页索引从 1 开始的服务。经过一些逻辑后,我得到了实体列表,我返回如下相同(响应)

totalCount = responses.size();
return new PageImpl<>(responses, pageable, totalCount);

当我请求第一页时

new PageRequest(1, 100)

我得到了回复

"content": [
       
            "id": "e1",
        
            "id": "2",
        
     ],
    "last": false,
    "totalElements": 102,
    "totalPages": 2,
    "size": 100,
    "number": 1,
    "sort": null,
    "first": true,
    "numberOfElements": 2

即使我有 "numberOfElements": 2 我也会返回 "totalElements": 102

我发现的问题是因为 PageImpl 中的 pageable.getOffset() 计算

this.total = !content.isEmpty() && pageable != null && pageable.getOffset() 
+ pageable.getPageSize() > total
                ? pageable.getOffset() + content.size() : total;

在我的第一页场景中,我的偏移量为 100 (1*100)。我该如何解决这个问题。

注意我使用第三方服务来获取索引为 1 的响应。所以我试图让我的服务与此保持一致,以便整个逻辑遵循相同的索引。

【问题讨论】:

如果有任何用途,您可以将 Spring Data 配置为在第一页使用 1 而不是 0,如下所述:***.com/questions/27032433/… 【参考方案1】:

您得到的结果是正确的,因为PageRequest 使用了从零开始的页面,如API docs 中所述:

参数

page - 从零开始的页面索引。

size - 要返回的页面的大小。

这意味着您正在检索第二页(而不是第一页),并且由于您的记录限制为 100 条,总共有 102 条记录,因此您将只检索最后两条。

您仍然可以公开一个从 1 开始的数字:

new PageRequest(page-1, 100);

或者,您可以通过实现Pageable 来自定义它。这允许您覆盖 Spring 数据使用的实际偏移量。

尽管如此,这并没有改变 Spring 数据期望 getPageNumber() 是从零开始的数字这一事实。您无法更改它,您只能在其之上添加一个抽象层以使其满足您的要求。

【讨论】:

您可以(或至少过去可以)为第一页 ***.com/a/27034846/1356423 配置 0/1。在 Spring 数据库的早期版本中,默认值实际上是 1。【参考方案2】:

那有什么问题? totalElements 告诉您数据源中存储了多少元素。 numberOfElements 告诉您当前页面包含多少元素。 当总共有 102 个元素并且您请求大小为 100 的页面 2 时,您应该会得到您收到的确切响应。

什么可能让你感到困惑:

使用new PageRequest(1, 100),您正在请求第二页,因为索引从0开始。

【讨论】:

是的。所以我希望 PageRequest 与服务保持一致,就像我给页面请求时一样 new PageRequest(1, 100) 它应该将其视为第一页。除了实现自定义 PageImpl 并覆盖偏移逻辑。 没有。那是你不会改变的东西!如果你想获得第一页,你必须做new PageRequest(0, 100)。无论如何,它有什么好处?在 Java 中(实际上在大多数语言中)索引都是从 0 开始的。 如果我这样做,总元素将是正确的,但页码将为 0,并且用户已请求页码 1。我有这种情况,因为为了获得响应,我使用第三方服务索引为 1。 这是一个索引。第一个索引总是从 0 开始。从 1 开始的索引通常会以问题告终。阅读这篇文章以获得科学推理:cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html 这样看:在new PageRequest(0, 100) 中,0 表示与可能的页面列表的偏移量。意味着您将跳过 0 页,进入第一页。拥有new PageRequest(1, 100) 意味着您想跳过 1 页并因此获得第 2 页。

以上是关于Spring Pagination 中的偏移量计算的主要内容,如果未能解决你的问题,请参考以下文章

如果数组大小发生变化以及定义的宏如何在此处计算偏移量,为啥 C 结构中的字符数组的偏移量会有所不同? [复制]

动态计算偏移量

在 MySQL 中计算时区的偏移量

Apollo 客户端中基于偏移量的分页错误

计算结构体内元素的偏移量宏

java中的偏移量和偏移地址是啥