Что такое интерфейс Pageable в Spring Data?

Ответ

Pageable — это интерфейс в Spring Data, абстрагирующий запрос на пагинацию (разбиение на страницы) и сортировку. Он передается в методы репозитория для возврата результатов по частям, что критически важно для работы с большими наборами данных.

Основные компоненты, которые инкапсулирует Pageable:

  1. Номер страницы (page) — начинается с 0.
  2. Размер страницы (size) — количество элементов на одной странице.
  3. Параметры сортировки (Sort) — поле(я) и направление сортировки (ASC/DESC).

Создание Pageable:

  • Автоматически из параметров HTTP-запроса (при поддержке Spring MVC):
    GET /api/users?page=0&size=20&sort=lastName,asc&sort=registrationDate,desc

    Spring создаст объект Pageable с соответствующими настройками.

  • Вручную с помощью PageRequest:
    // Страница 0, 10 элементов, сортировка по имени по возрастанию
    Pageable pageable = PageRequest.of(0, 10, Sort.by("name").ascending());
    // Сортировка по нескольким полям
    Pageable pageable = PageRequest.of(0, 10,
        Sort.by("lastName").ascending()
            .and(Sort.by("firstName").descending())
    );

Использование в репозитории:

public interface UserRepository extends JpaRepository<User, Long> {
    // Метод возвращает Page<User>, который содержит данные страницы и метаинформацию
    Page<User> findAllByActiveTrue(Pageable pageable);
}

Использование в сервисе или контроллере:

@GetMapping("/users")
public Page<UserDto> getUsers(Pageable pageable) {
    // Spring автоматически внедрит Pageable из параметров запроса
    return userService.findAll(pageable).map(UserDto::fromEntity);
}

Возвращаемый тип Page<T> содержит:

  • Контент страницы (List<T>).
  • Общее количество элементов.
  • Общее количество страниц.
  • Информацию о текущей странице и размере.

Это стандартный механизм Spring Data для эффективной и декларативной работы с постраничными данными.

Ответ 18+ 🔞

О, слушай, а вот эта штука Pageable в Spring — это ж просто пиздец как удобно, когда тебе надо выводить данные не все сразу, а по кускам, как пирог нарезать. Представь, у тебя в базе миллион юзеров, а ты их всех разом на фронт тянешь — это ж верный способ положить всё нахуй. А с пагинацией — красота: странички, сортировка, всё чинно-благородно.

Pageable — это такой интерфейс-обманщик, который прикидывается простым, а внутри упаковывает три главные вещи:

  1. Номер страницы (page) — счёт, блядь, с нуля идёт, не перепутай. Не как в книжке.
  2. Размер (size) — сколько строк на одной странице влезет.
  3. Сортировку (Sort) — по какому полю и в каком порядке это всё дело выстраивать.

Создаётся эта хуйня элементарно:

  • Автоматически, из запроса. Spring — он умный, ёпта. Кинул ему в контроллер параметры — он сам всё состряпает.

    GET /api/пользователи?page=0&size=20&sort=фамилия,asc&sort=датаРега,desc

    Он увидит это и подумает: "Ага, чувак хочет первую страницу, 20 штук, отсортированных по фамилии от А до Я, а потом по дате регистрации — свежих сверху". И создаст Pageable. Волшебство, блядь.

  • Вручную, через PageRequest. Если надо в коде наколдовать.

    // Страница первая (0), 10 записей, сортировка по имени по возрастанию
    Pageable pageable = PageRequest.of(0, 10, Sort.by("name").ascending());
    // А если надо по нескольким полям — пожалуйста, нате
    Pageable pageable = PageRequest.of(0, 10,
        Sort.by("lastName").ascending()
            .and(Sort.by("firstName").descending()) // Сначала по фамилии, потом по имени наоборот
    );

В репозитории это используется проще пареной репы:

public interface UserRepository extends JpaRepository<User, Long> {
    // Вот так вот. Метод вернёт не List, а Page. В нём будет и кусок данных, и всякая мета-хуйня.
    Page<User> findAllByActiveTrue(Pageable pageable);
}

Ну а в контроллере вообще красота:

@GetMapping("/users")
public Page<UserDto> getUsers(Pageable pageable) { // Spring сам его сюда воткнёт из запроса
    return userService.findAll(pageable).map(UserDto::fromEntity);
}

И что самое охуенное — метод возвращает не просто список, а Page<T>. Это такая обёртка, в которой есть:

  • Сам контент (List<T>) — данные текущей страницы.
  • Общее количество элементов во всей выборке (не на странице, а вообще!).
  • Общее количество страниц.
  • Ну и всякая служебная информация: какой сейчас номер страницы, какой размер и т.д.

Короче, не надо самому изобретать велосипед с limit и offset и считать общее количество отдельным запросом. Всё уже сделано, ёбана. Бери и пользуйся — это стандартный, ебучий, удобный механизм Spring Data.