跳到主要内容

分页与排序

DeepSeek V3 中英对照 Paging and Sorting

本节记录了 Spring Data REST 使用 Spring Data 仓库分页和排序抽象的方式。为了熟悉这些功能,请参阅您所使用的仓库实现(例如 Spring Data JPA)的 Spring Data 文档。

分页

Spring Data REST 不会从大型结果集中返回所有内容,而是识别一些 URL 参数,这些参数会影响页面大小和起始页码。

如果你扩展了 PagingAndSortingRepository<T, ID> 并访问所有实体的列表,你将获得前 20 个实体的链接。要将页面大小设置为其他数字,可以添加一个 size 参数,如下所示:

http://localhost:8080/people/?size=5

前面的示例将页面大小设置为 5。

要在你自己的查询方法中使用分页,你需要将方法签名更改为接受一个额外的 Pageable 参数,并返回一个 PageSlice 而不是 List。例如,以下查询方法被导出到 /people/search/nameStartsWith 并支持分页:

@RestResource(path = "nameStartsWith", rel = "nameStartsWith")
public Page findByNameStartsWith(@Param("name") String name, Pageable p);
java

Spring Data REST 导出器能够识别返回的 Page/Slice,并在响应体中返回结果,就像处理非分页响应一样,但它会在资源中添加额外的链接来表示上一页和下一页的数据。

上一页和下一页链接

每个分页响应都会根据当前页面,使用 IANA 定义的链接关系 prevnext 返回上一页和下一页的链接。然而,如果你当前位于结果的第一页,则不会渲染 prev 链接。对于结果的最后一页,也不会渲染 next 链接。

考虑以下示例,我们将页面大小设置为 5:

curl localhost:8080/people?size=5
{
"_links" : {
"self" : {
"href" : "http://localhost:8080/persons{&sort,page,size}", 1
"templated" : true
},
"next" : {
"href" : "http://localhost:8080/persons?page=1&size=5{&sort}", 2
"templated" : true
}
},
"_embedded" : {
… data …
},
"page" : { 3
"size" : 5,
"totalElements" : 50,
"totalPages" : 10,
"number" : 0
}
}
javascript

在顶部,我们可以看到 _links

  • self 链接提供了整个集合以及一些选项。

  • next 链接指向下一页,假设页面大小相同。

  • 底部是有关页面设置的额外数据,包括页面大小、总元素数、总页数以及您当前查看的页面编号。

备注

在命令行中使用诸如 curl 等工具时,如果语句中包含与号(&),你需要将整个 URI 用引号括起来。

请注意,selfnext URI 实际上是 URI 模板。它们不仅接受 size 作为参数,还可以接受 pagesort 作为可选标志。

如前所述,HAL 文档的底部包含了关于页面的详细信息。这些额外信息使得你可以轻松配置诸如滑块或指示器之类的 UI 工具,以反映用户在查看数据时的整体位置。例如,前面示例中的文档显示我们正在查看第一页(页码从 0 开始)。

以下示例展示了当我们点击 next 链接时会发生什么:

$ curl "http://localhost:8080/persons?page=1&size=5"
{
"_links" : {
"self" : {
"href" : "http://localhost:8080/persons{&sort,projection,page,size}",
"templated" : true
},
"next" : {
"href" : "http://localhost:8080/persons?page=2&size=5{&sort,projection}", 1
"templated" : true
},
"prev" : {
"href" : "http://localhost:8080/persons?page=0&size=5{&sort,projection}", 2
"templated" : true
}
},
"_embedded" : {
... data ...
},
"page" : {
"size" : 5,
"totalElements" : 50,
"totalPages" : 10,
"number" : 1 3
}
}
javascript

这看起来非常相似,除了以下区别:

  • next 链接现在指向了另一个页面,表明它与 self 链接的相对关系。

  • 现在出现了一个 prev 链接,为我们提供了返回上一页的路径。

  • 当前数字现在是 1(表示第二页)。

此功能允许你将屏幕上的可选按钮映射到这些超媒体控件,从而在不硬编码 URI 的情况下为 UI 体验实现导航功能。实际上,用户可以从页面大小列表中进行选择,动态更改所提供的内容,而无需重写顶部或底部的 nextprev 控件。

排序

Spring Data REST 能够识别使用存储库排序支持的排序参数。

要让你的结果按照特定属性排序,可以添加一个 sort URL 参数,并使用你想要排序的属性名称。你可以通过在属性名称后附加一个逗号(,),再加上 ascdesc 来控制排序的方向。以下示例将使用 PersonRepository 中定义的 findByNameStartsWith 查询方法,查找所有名称以字母 "K" 开头的 Person 实体,并添加排序数据,按 name 属性以降序排列结果:

curl -v "http://localhost:8080/people/search/nameStartsWith?name=K&sort=name,desc"

要根据多个属性对结果进行排序,请根据需要添加尽可能多的 sort=PROPERTY 参数。它们会按照在查询字符串中出现的顺序添加到 Pageable 中。结果可以按顶级属性和嵌套属性进行排序。使用属性路径表示法来表达嵌套的排序属性。不支持按可链接的关联(即指向顶级资源的链接)进行排序。