Spring DataReact式存储库页面计数和总计数

kh212irz  于 2023-02-11  发布在  Spring
关注(0)|答案(2)|浏览(110)

在spring Data中,我可以轻松地执行以下查询:

Page<MyClass> findByX(String x, Pageable pageable);

reactive Spring data(MongoDB)中,我找不到一种有效的方法来对结果进行分页。

Mono<Page<MyClass>> findByX(String x, Pageable pageable);

看起来是个不错的候选项,但失败了,错误是需要使用Flux.buffer(size, skip)
如果没有有效的方法,是否有一种方法可以在不使用Page的情况下获得查询总数,而无需实际执行一次查询?

bksxznpy

bksxznpy1#

Reactive Spring Data MongoDB存储库不提供为命令式存储库设计的分页功能。命令式分页在获取页面时需要额外的细节。特别是:

  • 分页查询返回的记录数
  • 如果返回的记录数为零或与页面大小匹配,则查询生成的记录总数可用于计算总页数

这两个方面都不符合高效、无阻塞资源使用的概念。等待接收到所有记录(以确定分页详细信息的第一块)将使您从被动式数据访问中获得的好处大部分消失。此外,执行计数查询的成本相当高,并且会增加延迟,直到您能够处理数据。
您仍然可以通过向存储库查询方法传递Pageable(PageRequest)来自己获取数据块:

Flux<MyClass> findByX(String x, Pageable pageable);

Spring Data将通过将Pageable转换为LIMIT和OFFSET来对查询应用分页。
Spring文档指出:

你可以试试下面的代码,我相信它应该为你工作得到计数

Mono<Long> countByXxxx(String x);
7gcisfzg

7gcisfzg2#

我是这样做的:

public Mono<Page<Role>> findByTenantId(TenantId id, Pageable page) {
    return roleRepository.countByTenantId(id)
            .zipWith(roleRepository.findByTenantId(id, page).collectList())
            .map(countAndItems -> new PageImpl<Role>(countAndItems.getT2(),
                    page, countAndItems.getT1()));
}

这样的话,两个结果项的流确实都是在加载完整个页面之后才开始的,我们需要先计算所有结果。

相关问题