← Назад к вопросам
Что такое интерфейс Pageable?
2.0 Middle🔥 181 комментариев
#Docker, Kubernetes и DevOps#JVM и управление памятью
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое интерфейс Pageable
Pageable — это интерфейс Spring Data, который инкапсулирует информацию о пагинации и сортировке для запросов к базе данных. Он позволяет легко реализовать постраничную выборку данных с сортировкой, не обращаясь к деталям SQL запросов.
Основные возможности Pageable
- Пагинация — получение определённой страницы данных
- Сортировка — сортировка результатов по полям
- Размер страницы — количество элементов на странице
- Номер страницы — какую страницу получить (начиная с 0)
Структура Pageable
public interface Pageable {
int getPageNumber(); // Номер страницы (начинается с 0)
int getPageSize(); // Размер страницы
long getOffset(); // Смещение (page * size)
Sort getSort(); // Объект сортировки
Pageable next(); // Следующая страница
Pageable previousOrFirst(); // Предыдущая страница
}
Пример использования
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;
// Entity
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private LocalDateTime createdAt;
// Getters/Setters
}
// Repository с поддержкой Pageable
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Page<User> findAll(Pageable pageable);
Page<User> findByName(String name, Pageable pageable);
}
// Service
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
// Получить первую страницу (20 элементов)
public Page<User> getAllUsers(int page, int size, String sortBy) {
Pageable pageable = PageRequest.of(page, size,
Sort.by(Sort.Direction.DESC, sortBy));
return userRepository.findAll(pageable);
}
}
// Controller
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public Page<User> getUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size,
@RequestParam(defaultValue = "id") String sortBy) {
return userService.getAllUsers(page, size, sortBy);
}
}
Использование Pageable в Controller
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductRepository productRepository;
// Spring автоматически преобразует query параметры в Pageable
@GetMapping
public Page<Product> getAllProducts(Pageable pageable) {
// http://localhost:8080/api/products?page=0&size=20&sort=name,desc
return productRepository.findAll(pageable);
}
// С фильтрацией
@GetMapping("/search")
public Page<Product> searchProducts(
@RequestParam String keyword,
Pageable pageable) {
// http://localhost:8080/api/products/search?keyword=laptop&page=0&size=10
return productRepository.findByNameContaining(keyword, pageable);
}
}
Создание Pageable вручную
public class PageableExamples {
public static void main(String[] args) {
// Пример 1: Простая пагинация
Pageable page1 = PageRequest.of(0, 20); // Первая страница, 20 элементов
// Пример 2: С сортировкой
Pageable page2 = PageRequest.of(0, 20,
Sort.by("name").ascending());
// Пример 3: Сортировка по нескольким полям
Pageable page3 = PageRequest.of(0, 20,
Sort.by("createdAt").descending()
.and(Sort.by("name").ascending()));
// Пример 4: Сортировка с направлением
Pageable page4 = PageRequest.of(0, 20,
Sort.by(new Sort.Order(Sort.Direction.DESC, "createdAt"),
new Sort.Order(Sort.Direction.ASC, "name")));
}
}
Работа с результатами Page<T>
public class PageResultsHandling {
public void handleResults() {
// Page наследует Collection и содержит дополнительную информацию
Page<User> page = userRepository.findAll(PageRequest.of(0, 20));
// Получить содержимое страницы
List<User> users = page.getContent();
// Информация о странице
int totalPages = page.getTotalPages(); // Всего страниц
long totalElements = page.getTotalElements(); // Всего элементов
int pageNumber = page.getNumber(); // Номер текущей страницы
int pageSize = page.getSize(); // Размер страницы
int numberOfElements = page.getNumberOfElements(); // Элементов на текущей странице
// Проверки
boolean isFirst = page.isFirst(); // Первая ли это страница
boolean isLast = page.isLast(); // Последняя ли это страница
boolean hasNext = page.hasNext(); // Есть ли следующая
boolean hasPrevious = page.hasPrevious(); // Есть ли предыдущая
// Навигация
Pageable next = page.nextPageable(); // Pageable для следующей
Pageable previous = page.previousPageable(); // Pageable для предыдущей
}
}
Фильтрация с Pageable
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// Простой поиск
Page<User> findByName(String name, Pageable pageable);
// По нескольким полям
Page<User> findByNameAndEmail(String name, String email, Pageable pageable);
// С использованием Query
@Query("SELECT u FROM User u WHERE u.createdAt >= :startDate")
Page<User> findRecentUsers(@Param("startDate") LocalDateTime startDate,
Pageable pageable);
// Кастомный запрос с динамической сортировкой
@Query("SELECT u FROM User u WHERE LOWER(u.name) LIKE LOWER(concat('%', :keyword, '%'))")
Page<User> searchUsers(@Param("keyword") String keyword, Pageable pageable);
}
@Service
public class UserSearchService {
@Autowired
private UserRepository userRepository;
public Page<User> searchUsers(String keyword, int page, int size) {
Pageable pageable = PageRequest.of(page, size,
Sort.by(Sort.Direction.DESC, "createdAt"));
return userRepository.searchUsers(keyword, pageable);
}
}
REST API ответ с пагинацией
// JSON ответ выглядит так:
{
"content": [
{"id": 1, "name": "John", "email": "john@example.com"},
{"id": 2, "name": "Jane", "email": "jane@example.com"}
],
"pageable": {
"pageNumber": 0,
"pageSize": 20,
"sort": {"unsorted": false}
},
"totalPages": 5,
"totalElements": 100,
"last": false,
"size": 20,
"number": 0,
"sort": {"unsorted": false, "sorted": true, "empty": false},
"numberOfElements": 20,
"first": true,
"empty": false
}
Валидация Pageable
@RestController
public class UserController {
@GetMapping("/users")
public Page<User> getUsers(
@Valid Pageable pageable) {
// Spring Data валидирует Pageable автоматически
// Максимальный размер страницы: 100
// По умолчанию: page=0, size=20
return userRepository.findAll(pageable);
}
}
// Конфигурация валидации
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
PageableHandlerMethodArgumentResolver resolver =
new PageableHandlerMethodArgumentResolver();
resolver.setPageParameterName("page");
resolver.setSizeParameterName("size");
resolver.setOneIndexedParameters(false); // Нумерация с 0
resolver.setMaxPageSize(100);
resolver.setDefaultPageSize(20);
resolvers.add(resolver);
}
}
Практический пример: Поиск товаров
@RestController
@RequestMapping("/api/products")
public class ProductController {
@Autowired
private ProductService productService;
// GET /api/products?page=0&size=20&sort=price,desc
@GetMapping
public ResponseEntity<Page<ProductDTO>> getProducts(
@RequestParam(required = false) String category,
@RequestParam(required = false) Double minPrice,
@RequestParam(required = false) Double maxPrice,
Pageable pageable) {
Page<ProductDTO> products =
productService.searchProducts(category, minPrice, maxPrice, pageable);
return ResponseEntity.ok(products);
}
}
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
public Page<ProductDTO> searchProducts(
String category, Double minPrice, Double maxPrice, Pageable pageable) {
Page<Product> products = productRepository.findByFilters(
category, minPrice, maxPrice, pageable);
return products.map(ProductDTO::fromProduct);
}
}
Преимущества Pageable
- Простота — не нужно вручную считать LIMIT и OFFSET
- Стандартизация — единый способ работы с пагинацией
- Интеграция — автоматическое преобразование query параметров
- Безопасность — валидация размеров страниц
- Гибкость — лёгкая сортировка по разным полям
Pageable — это незаменимый инструмент для работы с большими наборами данных в Spring приложениях, обеспечивая удобную и безопасную пагинацию данных.