分页与排序

本节文档介绍了 Spring Data REST 如何使用 Spring Data Repository 的分页和排序抽象功能。要熟悉这些特性,请参阅您所使用的仓库实现(例如 Spring Data JPA)对应的 Spring Data 文档。spring-doc.cadn.net.cn

分页

Spring Data REST 能识别一些 URL 参数,用于控制页面大小和起始页码,而不是从大型结果集中返回所有内容。spring-doc.cadn.net.cn

如果你继承了 PagingAndSortingRepository<T, ID> 并访问所有实体的列表,你会获得前 20 个实体的链接。若要将页面大小设置为其他数值,请添加一个 size 参数,如下所示:spring-doc.cadn.net.cn

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

前面的示例将页面大小设置为5。spring-doc.cadn.net.cn

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

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

Spring Data REST 导出器能够识别返回的 Page/Slice,并将结果放入响应体中,其方式与非分页响应相同,但会在资源中添加额外的链接,用于表示数据的上一页和下一页。spring-doc.cadn.net.cn

每个分页响应都会根据当前页面,使用 IANA 定义的链接关系 prevnext 返回上一页和下一页结果的链接。但是,如果您当前位于第一页结果,则不会渲染 prev 链接。对于最后一页结果,不会渲染 next 链接。spring-doc.cadn.net.cn

请考虑以下示例,其中我们将页面大小设置为5:spring-doc.cadn.net.cn

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
  }
}

在顶部,我们看到 _linksspring-doc.cadn.net.cn

1 self 链接用于提供整个集合,并附带一些选项。
2 next 链接指向下一页,假设页面大小相同。
3 底部是有关页面设置的额外数据,包括页面大小、总元素数量、总页数以及您当前正在查看的页码。
在命令行中使用 curl 等工具时,如果您的语句中包含一个与号(&),您需要用引号将整个 URI 括起来。

请注意,selfnext URI 实际上是 URI 模板。它们不仅接受 size,还接受 pagesort 作为可选参数。spring-doc.cadn.net.cn

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

以下示例展示了当我们跟随 next 链接时会发生什么:spring-doc.cadn.net.cn

$ 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)
  }
}

这看起来非常相似,除了以下几点不同之处:spring-doc.cadn.net.cn

1 next 链接现在指向另一页,表明它相对于 self 链接的相对视角。
2 现在出现了一个 prev 链接,为我们提供了返回上一页的路径。
3 当前数字现在为 1(表示第二页)。

此功能允许您将界面上的可选按钮映射到这些超媒体控件,从而在无需硬编码 URI 的情况下实现 UI 导航功能。实际上,用户可以从页面大小列表中进行选择,动态更改所呈现的内容,而无需重写顶部或底部的 next1 控件。spring-doc.cadn.net.cn

排序

Spring Data REST 能识别使用仓库排序支持的排序参数。spring-doc.cadn.net.cn

若要按特定属性对结果进行排序,请添加一个名为 sort 的 URL 参数,并指定您希望用于排序结果的属性名称。您可以通过在属性名称后附加一个逗号(,)以及 ascdesc 来控制排序方向。以下示例将使用 findByNameStartsWith 上定义的 PersonRepository 查询方法,查找所有姓名以字母“K”开头的 Person 实体,并添加排序数据,使结果按 name 属性以降序排列:spring-doc.cadn.net.cn

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

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