SeedStack 存储库中的分页

Pagination in SeedStack Repositories

在我的 Java 项目中,使用 SeedStack,我查询使用如下规范从聚合中检索数据:

更新:已修复代码示例以显示正确的 return 类型方法

public interface ProductRepository extends Repository<Product, ProductId> {
    default Stream<Product> discontinuedProducts() {
        return get(getSpecificationBuilder().of(Product.class)
                .property("discontinued").equalTo(true)
                .build()
        );
    }
}

为了避免潜在的内存不足错误,我想使用分页来拆分在某些存储库查询中检索到的数据。

此外,我想使用与字符串数据存储库中现有的分页功能非常相似的东西。我想保留结果的一些元素(而不是全部)并通过 "page" 处理它们,而不将所有数据结果保存在一个集合中。

Spring中的分页和排序:https://docs.spring.io/spring-data/rest/docs/2.0.0.M1/reference/html/paging-chapter.html

但是,我阅读了 SeedStack 文档,但没有找到此功能。

SeedStack 中的存储库: http://seedstack.org/docs/business/repositories/

所以,我想知道使用 SeedStack 对查询结果进行分页的最佳方法是什么。

SeedStack 提供帮助程序以多种不同方式进行分页,但遗憾的是缺少这方面的文档。

在我们进入细节之前请注意你的discontinuedProducts()方法应该return一个Stream<Product>而不是List<Product>因为get方法存储库 return 是一个流。

使用 SeedStack 进行分页的主要方法是使用插入存储库顶部的 Paginator DSL 来提供分页。

示例 1(直接对流进行分页):

public class SomeResource {
    @Inject
    private Paginator paginator;
    @Inject
    private ProductRepository productRepository;
    @Inject
    private FluentAssembler fluentAssembler;

    public void someMethod() {
        Page<Product> page = paginator.paginate(productRepository.discontinuedProducts())
                .byPage(1)
                .ofSize(10)
                .all();
    }
}

示例 2(使用规范对存储库进行分页):

public class SomeResource {
    @Inject
    private Paginator paginator;
    @Inject
    private ProductRepository productRepository;
    @Inject
    private SpecificationBuilder specificationBuilder;

    public void someMethod() {
        Page<Product> page = paginator.paginate(productRepository)
                .byPage(1)
                .ofSize(10)
                .matching(specificationBuilder.of(Product.class)
                    .property("discontinued").equalTo(true)
                    .build());
    }
}

示例 3(在组合中添加 DTO 映射):

public class SomeResource {
    @Inject
    private Paginator paginator;
    @Inject
    private ProductRepository productRepository;
    @Inject
    private SpecificationBuilder specificationBuilder;
    @Inject
    private FluentAssembler fluentAssembler;

    public void someMethod() {
        Page<ProductDto> page = fluentAssembler.assemble(
                paginator.paginate(productRepository)
                    .byPage(1)
                    .ofSize(10)
                    .matching(specificationBuilder.of(Product.class)
                        .property("discontinued").equalTo(true)
                        .build()))
                .toPageOf(ProductDto.class)
    }
}

在最后一个示例中,SeedStack 将:

  • 将分页谓词添加到您的自定义规范中,
  • 将生成的规范转换为适当的持久性查询,
  • 获取数据并将其放入页面,
  • 使用正确的汇编程序将域聚合页面转换为 DTO 页面。

Note that if you are going to reuse the same specification over and over, it may be useful to turn it into a class (like DiscontinuedProductSpec) or create a method in your repository to build it (like buildDiscontinuedProductSpec()).

还有其他几种方法可以组合这些工具,请查看 Paginator, FluentAssembler and Repository. You can also have a look at the pagination integration test 的 Javadoc 以获取更多示例。