Using Pagination
Learn how pagination can be implemented to avoid overloading the database.
Why do we need pagination?
We currently load all users from the database in one big table and present that. To avoid overloading the database, we should implement pagination. That will let us get users in batches of ten or twenty users, for example. This allows us to specify the number of users to retrieve in one query and display it on a single page.
Pagination in Spring
Spring Data JPA makes it very easy to implement pagination. We need to change our UserRepository
to extend PagingAndSortingRepository
as opposed to CrudRepository
:
package com.tamingthymeleaf.application.user;import org.springframework.data.repository.PagingAndSortingRepository;import org.springframework.transaction.annotation.Transactional;@Transactional(readOnly = true)public interface UserRepository extends PagingAndSortingRepository<User, UserId>, UserRepositoryCustom {}
By doing so, our repository now allows us to get entities in pages. From the PagingAndSortingRepository
source code:
/*** Returns a {@link Page} of entities meeting the paging restriction provided inthe {@code Pageable} object.** @param pageable* @return a page of entities*/Page<T> findAll(Pageable pageable);
The Pageable
interface represents the input parameters that will allow the database to return the correct set of
results. Page
represents those results together with some metadata like the total number of pages and the total number of elements.
Testing pagination
We can test our new paging capability by writing an extra test in UserRepositoryTest
:
@Testvoid testFindAllPageable() {saveUsers(8); //<.>Sort sort = Sort.by(Sort.Direction.ASC, "userName.lastName", "userName.firstName"); //<.>assertThat(repository.findAll(PageRequest.of(0, 5, sort))) //<.>.hasSize(5) //<.>.extracting(user -> user.getUserName().getFullName()) //<.>.containsExactly("Tommy1 Holt", "Tommy3 Holt", "Tommy5 Holt", "Tommy7 Holt", "Tommy0 Walton"); //<.>assertThat(repository.findAll(PageRequest.of(1, 5, sort))) //<.>.hasSize(3).extracting(user -> user.getUserName().getFullName()).containsExactly("Tommy2 Walton", "Tommy4 Walton", "Tommy6 Walton");assertThat(repository.findAll(PageRequest.of(2, 5, sort))).isEmpty(); //<.>}private void saveUsers(int numberOfUsers) {for (int i = 0; i < numberOfUsers; i++) {repository.save(new User(repository.nextId(),new UserName(String.format("Tommy%d", i), i % 2 == 0 ? "Walton" : "Holt"),Gender.MALE,LocalDate.of(2001, Month.FEBRUARY, 17),new Email("tommy.walton" + i +"@gmail.com"),new PhoneNumber("202 555 0192")));}}
- Save eight users in the database to set up the test.
- In order to make paging work properly, we always need to assign a sort order. Otherwise, we can never be sure of what part of the data the database