【问题标题】:Pagination in SeedStack RepositoriesSeedStack 存储库中的分页
【发布时间】:2019-09-18 12:59:31
【问题描述】:

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

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

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

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

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

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 对查询结果进行分页的最佳方法是什么。

【问题讨论】:

    标签: java jpa pagination out-of-memory seedstack


    【解决方案1】:

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

    在我们详细介绍之前,请注意您的discontinuedProducts() 方法应该返回Stream&lt;Product&gt; 而不是List&lt;Product&gt;,因为存储库的get 方法返回一个流。

    使用 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 页面。

    请注意,如果您要反复重用相同的规范,将其转换为类(如DiscontinuedProductSpec)或在您的存储库中创建一个方法来构建它(如buildDiscontinuedProductSpec())可能会很有用.

    还有其他几种组合这些工具的方法,请查看PaginatorFluentAssemblerRepository 的Javadoc。您还可以查看pagination integration test 了解更多示例。

    【讨论】:

    • 确实,discontinuedProducts() 返回的是 Stream&lt;Product&gt; 而不是 List&lt;Product&gt;。然后,我要修复它。但是,我从 SeedStack Repositories 文档中获取了这个示例来解释我的问题,而没有我的应用程序的邮政编码。所以,我认为也许文档也应该修复。否则,这个答案真的很有用,我将检查 Javadoc 来决定我将如何在我的应用程序中分页。
    • 我刚刚修复了文档以显示 Stream 而不是 Listreturn 值。感谢您发现错误!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-29
    • 2018-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多