Gymterview
junior

Как реализовать пагинацию и сортировку в Spring Data JPA?

Spring Data предоставляет абстракции для пагинации и сортировки через интерфейсы Pageable, Sort, Page и Slice.

Сортировка

Пример
List<User> users = userRepository.findByStatus("ACTIVE",
    Sort.by(Sort.Direction.ASC, "lastName"));

Sort sort = Sort.by("lastName").ascending()
               .and(Sort.by("firstName").ascending());

Пагинация

Пример
Pageable pageable = PageRequest.of(0, 20, Sort.by("lastName").ascending());
Page<User> page = userRepository.findByStatus("ACTIVE", pageable);

page.getContent();          // List<User> -- данные текущей страницы
page.getTotalElements();    // общее количество элементов
page.getTotalPages();       // общее количество страниц
page.getNumber();           // номер текущей страницы (с 0)
page.hasNext();             // есть ли следующая страница

Slice vs Page

Page выполняет дополнительный COUNT(*) для подсчёта общего количества. Slice этого не делает – только знает, есть ли следующая страница. Slice быстрее для больших таблиц.

Пагинация в контроллере

Пример
@GetMapping
public Page<UserDto> getUsers(
        @RequestParam(defaultValue = "0") int page,
        @RequestParam(defaultValue = "20") int size,
        @RequestParam(defaultValue = "lastName,asc") String[] sort) {

    Pageable pageable = PageRequest.of(page, size, Sort.by(
        Sort.Order.by(sort[0]).with(Sort.Direction.fromString(sort[1]))));
    return userRepository.findByStatus("ACTIVE", pageable).map(this::toDto);
}

На собеседовании: покажите понимание разницы Page vs Slice и когда что использовать. Частая ошибка – загружать все данные в память и делать пагинацию на уровне Java. Также – не ограничивать максимальный size, позволяя клиенту запросить size=1000000.