简体   繁体   中英

Pagination in SeedStack Repositories

In my Java project, using SeedStack, I have queries to retrive data from an aggregate using specifications like this:

UPDATE: Code example fixed to show the correct return type method

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

In order to avoid potential out-of-memory errors, I want to use pagination to split data retrieved in some repository queries.

Moreover, I would like to use something very similar to pagination feature existing in String Data Repositories. I would like to keep some elements of the result (and not all of them) and process them by "page" without keeping all the data result in a Collection.

Paging and Sorting in Spring: https://docs.spring.io/spring-data/rest/docs/2.0.0.M1/reference/html/paging-chapter.html

However, I read SeedStack documentation and I did not find this feature.

Repositories in SeedStack: http://seedstack.org/docs/business/repositories/

So, I want to know what is the best way to paginate query results using SeedStack.

SeedStack provides helpers to do pagination in several differents ways but sadly the documentation is lacking on this front.

Before we go into details please note that you discontinuedProducts() method should return a Stream<Product> and not a List<Product> because the get method of the repository returns a stream.

The main way to do pagination with SeedStack is to use the Paginator DSL which plugs on top of a repository to provide the pagination.

Example 1 (paginating the stream directly):

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

Example 2 (paginating the repository with a spec):

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

Example 3 (adding the DTO mapping in the mix):

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

In this last example, SeedStack will:

  • Add a pagination predicate to your custom specification,
  • Convert the resulting specification into the proper persistence query,
  • Fetch the data and put it in a page,
  • Convert the page of domain aggregate to a page of DTO using the correct assembler.

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() ).

There are several other ways to combine these tools, please check the Javadoc of the Paginator , FluentAssembler and Repository . You can also have a look at the pagination integration test for more examples.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM