使用 Spring Data 中的 CassandraRepository 实现 Cassandra 分页的正确方法

rie*_*pil 5 java cassandra spring-data spring-boot spring-data-cassandra

我正在寻找一种解决方案,通过 Cassandra(版本)数据库为基于 Spring Boot 的 REST 服务实现分页3.11.3。我们使用 Spring Boot2.0.5.RELEASE作为spring-boot-starter-data-cassandra依赖项。

由于 Spring Data 的CassandraRepository<T, ID>接口没有扩展,PagingAndSortingRepository我们无法获得像JPA.

我阅读了 Spring Data Cassandra 文档,并找到了一种使用 Cassandra 和 Spring Data 实现分页的可能方法,因为该CassandraRepository接口具有以下可用方法Slice<T> findAll(Pageable pageable);。我知道 Cassandra 无法获取特定的临时页面,并且始终需要第 0 页来迭代所有页面,如下所示CassandraPageRequest

Cassandra 特定的 {@link PageRequest} 实现提供对 {@link PagingState} 的访问。此类允许创建第一个页面请求,并表示通过 Cassandra 分页基于获取页面的进度,并允许仅向前导航。访问特定页面需要获取所有页面,直到到达所需页面。

在我的用例中,我们有 > 1.000.000 个数据库条目,并且希望在单页应用程序中分页显示它们。

我当前的方法如下所示:

@RestController
@RequestMapping("/users")
public class UsersResource {

  @Autowired
  UserRepository    userRepository;

  @GetMapping
  public ResponseEntity<List<User>> getAllTests(
            @RequestParam(defaultValue = "0", name = "page") @Positive int requiredPage, 
            @RequestParam(defaultValue = "500", name = "size") int size) {

    Slice<User> resultList = userRepository.findAll(CassandraPageRequest.first(size));

    int currentPage = 0;

    while (resultList.hasNext() && currentPage <= requiredPage) {
      System.out.println("Current Page Number: " + currentPage);
      resultList = userRepository.findAll(resultList.nextPageable());
      currentPage++;
    }

    return ResponseEntity.ok(resultList.getContent());
  }
}
Run Code Online (Sandbox Code Playgroud)

但是使用这种方法,我必须找到请求的页面,同时将所有数据库条目提取到内存并迭代,直到找到正确的页面。是否有不同的方法来找到正确的页面,或者我是否必须使用当前的解决方案?

我的 Cassandra 表定义如下所示:

CREATE TABLE user (
  id int, firstname varchar, 
  lastname varchar, 
  code varchar, 
  PRIMARY KEY(id)
);
Run Code Online (Sandbox Code Playgroud)

Ped*_*lli 2

我所做的是创建一个包含内容和 pagingState 哈希的页面对象。

在初始页面中,我们有简单的分页

Pageable pageRequest = CassandraPageRequest.of(0,5);

一旦执行查找,我们就得到了切片

Slice<Group> slice = groupRepository.findAll(pageRequest);

通过切片可以获得分页状态

page.setPageHash(getPageHash((CassandraPageRequest) slice.getPageable()));

在哪里

private String getPageHash(CassandraPageRequest pageRequest) { return Base64.toBase64String(pageRequest.getPagingState().toBytes()); }

最后返回一个Page对象,其中包含List内容和pageHash的pagingState