分页和排序
本节介绍了 Spring Data REST 如何使用 Spring Data Repository 的分页和排序抽象。要熟悉这些特性,请参阅您使用的 repository 实现对应的 Spring Data 文档(例如 Spring Data JPA)。
分页
Spring Data REST 不会返回大型结果集中的所有内容,而是会识别一些影响页大小和起始页码的 URL 参数。
如果您扩展了 PagingAndSortingRepository<T, ID>
并访问所有实体的列表,您将获得指向前 20 个实体的链接。要将页大小设置为其他任何数字,请添加一个 size
参数,如下所示
http://localhost:8080/people/?size=5
前面的示例将页大小设置为 5。
要在您自己的查询方法中使用分页,您需要更改方法签名,使其接受额外的 Pageable
参数,并返回 Page
或 Slice
而不是 List
。例如,以下查询方法会导出到 /people/search/nameStartsWith
并支持分页
@RestResource(path = "nameStartsWith", rel = "nameStartsWith")
public Page findByNameStartsWith(@Param("name") String name, Pageable p);
Spring Data REST 导出器会识别返回的 Page
/Slice
并在响应体中为您提供结果,就像它处理非分页响应一样,但会向资源添加额外的链接来表示数据的前一页和下一页。
上一页和下一页链接
每个分页响应都会使用 IANA 定义的链接关系 prev
和 next
,基于当前页返回指向结果的前一页和下一页的链接。但是,如果您当前位于第一页结果,则不会渲染 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
}
}
在顶部,我们看到 _links
1 | self 链接提供了包含一些选项的完整集合。 |
2 | next 链接指向下一页,假设页大小相同。 |
3 | 底部是关于页设置的额外数据,包括页大小、总元素数、总页数以及您当前正在查看的页码。 |
在命令行上使用 curl 等工具时,如果您的语句中包含与号 (& ),则需要将整个 URI 用引号括起来。 |
请注意,self
和 next
URI 实际上是 URI 模板。它们不仅接受 size
,还接受 page
和 sort
作为可选标志。
如前所述,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)
}
}
这看起来非常相似,除了以下几点不同
1 | next 链接现在指向另一页,表示它相对于 self 链接的视角。 |
2 | 现在出现一个 prev 链接,为我们提供了回到上一页的路径。 |
3 | 当前页码现在是 1(表示第二页)。 |
此功能允许您将屏幕上的可选按钮映射到这些超媒体控件,使您无需硬编码 URI 即可实现 UI 体验的导航功能。事实上,用户可以从页大小列表中选择,动态更改提供的内容,而无需重写顶部或底部的 next
和 prev
控件。
排序
Spring Data REST 识别使用 repository 排序支持的排序参数。
要按特定属性对结果进行排序,请添加一个 sort
URL 参数,其值为要排序的属性名称。您可以通过在属性名称后附加逗号 (,
) 以及 asc
或 desc
来控制排序方向。以下示例将使用在 PersonRepository
上定义的 findByNameStartsWith
查询方法,针对所有名称以字母“K”开头的 Person
实体,并添加按 name
属性降序排列的排序数据。
curl -v "http://localhost:8080/people/search/nameStartsWith?name=K&sort=name,desc"
要按多个属性对结果进行排序,请根据需要添加任意数量的 sort=PROPERTY
参数。它们会按照在查询字符串中出现的顺序添加到 Pageable
中。结果可以按顶级属性和嵌套属性排序。使用属性路径表示法来表达嵌套排序属性。不支持按可链接关联(即指向顶级资源的链接)进行排序。