Пагинация и фильтрация данных в REST API с использованием Spring
При работе с большими наборами данных в REST API критически важна поддержка пагинации и фильтрации. Они позволяют улучшить производительность приложения, сократить нагрузку на сервер и предоставить клиентам удобные способы получать нужные данные.
1. Пагинация (Pagination) в Spring
Пагинация позволяет разделить большие объемы данных на страницы и возвращать их по частям. В Spring Boot пагинация реализуется с помощью Spring Data JPA.
Подключение пагинации в проекте
Spring Data JPA предоставляет интерфейсы и аннотации для легкой реализации пагинации.
Добавьте параметр Pageable в методы репозитория:
Page — это контейнер, который содержит данные текущей страницы и мета-информацию (например, общее количество страниц).
Pageable — это интерфейс для параметров пагинации: номер страницы, размер страницы и сортировка.
Использование Pageable в контроллере:
Пример запроса с пагинацией:
Пример ответа:
2. Фильтрация данных в REST API
Фильтрация позволяет клиентам задавать условия, по которым нужно отбирать данные.
Подходы к фильтрации
Фильтрация по параметрам запроса (Request Parameters): Используется для простой фильтрации данных.
Динамическая фильтрация с помощью Specification или Criteria:
Применяется для сложных и многоуровневых условий.
Фильтрация по параметрам запроса
Реализация простого поиска с фильтрацией:
Добавьте методы в репозиторий:
#Java #Training #Spring #Pagination #Filter
При работе с большими наборами данных в REST API критически важна поддержка пагинации и фильтрации. Они позволяют улучшить производительность приложения, сократить нагрузку на сервер и предоставить клиентам удобные способы получать нужные данные.
1. Пагинация (Pagination) в Spring
Пагинация позволяет разделить большие объемы данных на страницы и возвращать их по частям. В Spring Boot пагинация реализуется с помощью Spring Data JPA.
Подключение пагинации в проекте
Spring Data JPA предоставляет интерфейсы и аннотации для легкой реализации пагинации.
Добавьте параметр Pageable в методы репозитория:
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
Page<User> findAll(Pageable pageable);
}
Page — это контейнер, который содержит данные текущей страницы и мета-информацию (например, общее количество страниц).
Pageable — это интерфейс для параметров пагинации: номер страницы, размер страницы и сортировка.
Использование Pageable в контроллере:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserRepository userRepository;
@Autowired
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@GetMapping
public ResponseEntity<Page<User>> getAllUsers(Pageable pageable) {
Page<User> users = userRepository.findAll(pageable);
return ResponseEntity.ok(users);
}
}
Пример запроса с пагинацией:
GET /api/users?page=0&size=5&sort=name,asc
page — номер страницы (начинается с 0).
size — количество элементов на странице.
sort — параметры сортировки (поле,направление).
Пример ответа:
{
"content": [
{"id": 1, "name": "John", "email": "john@example.com"},
{"id": 2, "name": "Jane", "email": "jane@example.com"}
],
"pageable": {
"pageNumber": 0,
"pageSize": 5
},
"totalPages": 2,
"totalElements": 10,
"last": false
}
2. Фильтрация данных в REST API
Фильтрация позволяет клиентам задавать условия, по которым нужно отбирать данные.
Подходы к фильтрации
Фильтрация по параметрам запроса (Request Parameters): Используется для простой фильтрации данных.
Динамическая фильтрация с помощью Specification или Criteria:
Применяется для сложных и многоуровневых условий.
Фильтрация по параметрам запроса
Реализация простого поиска с фильтрацией:
Добавьте методы в репозиторий:
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByNameContaining(String name);
List<User> findByAgeGreaterThanEqual(Integer age);
}
#Java #Training #Spring #Pagination #Filter
Добавьте фильтры в контроллер:
Примеры запросов:
Фильтрация по имени:
Фильтрация по возрасту:
Динамическая фильтрация с использованием Specification
Для сложных фильтров можно использовать Spring Data JPA Specification.
Добавьте зависимость:
Создайте Specification для фильтрации:
Расширьте репозиторий:
Добавьте динамическую фильтрацию в контроллер:
Пример запроса с фильтрацией:
3. Пагинация и фильтрация вместе
Совмещение пагинации и фильтрации:
Пример запроса:
#Java #Training #Spring #Pagination #Filter
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserRepository userRepository;
@Autowired
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@GetMapping("/search")
public ResponseEntity<List<User>> searchUsers(
@RequestParam(required = false) String name,
@RequestParam(required = false) Integer age) {
if (name != null) {
return ResponseEntity.ok(userRepository.findByNameContaining(name));
} else if (age != null) {
return ResponseEntity.ok(userRepository.findByAgeGreaterThanEqual(age));
} else {
return ResponseEntity.ok(userRepository.findAll());
}
}
}
Примеры запросов:
Фильтрация по имени:
GET /api/users/search?name=John
Фильтрация по возрасту:
GET /api/users/search?age=30
Динамическая фильтрация с использованием Specification
Для сложных фильтров можно использовать Spring Data JPA Specification.
Добавьте зависимость:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Создайте Specification для фильтрации:
import org.springframework.data.jpa.domain.Specification;
public class UserSpecification {
public static Specification<User> hasName(String name) {
return (root, query, cb) -> cb.like(root.get("name"), "%" + name + "%");
}
public static Specification<User> hasAgeGreaterThan(Integer age) {
return (root, query, cb) -> cb.greaterThanOrEqualTo(root.get("age"), age);
}
}
Расширьте репозиторий:
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
}
Добавьте динамическую фильтрацию в контроллер:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/users")
public class UserController {
private final UserRepository userRepository;
@Autowired
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
@GetMapping("/filter")
public ResponseEntity<List<User>> filterUsers(
@RequestParam(required = false) String name,
@RequestParam(required = false) Integer age) {
Specification<User> spec = Specification.where(null);
if (name != null) {
spec = spec.and(UserSpecification.hasName(name));
}
if (age != null) {
spec = spec.and(UserSpecification.hasAgeGreaterThan(age));
}
return ResponseEntity.ok(userRepository.findAll(spec));
}
}
Пример запроса с фильтрацией:
GET /api/users/filter?name=Jane&age=25
3. Пагинация и фильтрация вместе
Совмещение пагинации и фильтрации:
@GetMapping("/filter")
public ResponseEntity<Page<User>> filterUsers(
@RequestParam(required = false) String name,
@RequestParam(required = false) Integer age,
Pageable pageable) {
Specification<User> spec = Specification.where(null);
if (name != null) {
spec = spec.and(UserSpecification.hasName(name));
}
if (age != null) {
spec = spec.and(UserSpecification.hasAgeGreaterThan(age));
}
Page<User> result = userRepository.findAll(spec, pageable);
return ResponseEntity.ok(result);
}
Пример запроса:
GET /api/users/filter?name=Jane&page=0&size=5&sort=age,desc
#Java #Training #Spring #Pagination #Filter