Paging and Sorting

本节记录了 Spring Data REST 如何使用 Spring Data Repository 分页和分类抽象。若要熟悉这些功能,请参阅你使用的存储库实现(例如 Spring Data JPA)的 Spring Data 文档。

Paging

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);

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

在顶部,我们会看到 _links

1 `self`链接提供了整个集合,其中包含一些选项。
2 `next`链接指向下一页,假设分页大小相同。
3 底部包含有关页面设置的额外数据,包括分页大小、总元素、总页数以及您当前正在查看的页码。

在命令行上使用 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
  }
}

除了以下不同之处,这看起来非常相似:

1 `next`链接现在指向了另一页,指示了它与 `self`链接的相对透视图。
2 现在出现了 `prev`链接,为我们提供了一条通向前一页的路径。
3 当前编号现在为 1(表示第二页)。

此功能允许您将屏幕上的可选按钮映射到这些超媒体控件,使您能够针对 UI 体验实现导航功能,而无需对 URI 进行硬编码。事实上,用户可以选择页面大小列表,动态更改提供的内容,而无需重写顶部或底部的 nextprev 控件。

Sorting

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 中。可以按顶级和嵌套属性对结果进行排序。使用属性路径表示法来表示嵌套排序属性。不支持按可链接关联(即,指向顶级资源的链接)进行排序。