Ответ
Spring Data JPA предоставляет несколько основных способов для создания пользовательских запросов.
1. Query Creation (Соглашения об именовании методов) Репозиторий автоматически строит запрос на основе имени метода. Подходит для простых условий.
List<User> findByLastNameAndActiveTrue(String lastName);
Page<User> findByEmailContaining(String email, Pageable pageable);
2. Аннотация @Query (JPQL или нативный SQL)
Наиболее гибкий и часто используемый способ для сложных запросов.
// JPQL-запрос (работает с сущностями)
@Query("SELECT u FROM User u WHERE u.email = :email AND u.active = true")
Optional<User> findActiveUserByEmail(@Param("email") String email);
// Нативный SQL-запрос (работает с таблицами)
@Query(value = "SELECT * FROM users WHERE created_at > :date", nativeQuery = true)
List<User> findUsersCreatedAfter(@Param("date") LocalDateTime date);
3. Кастомные репозитории (Custom Repository Implementation)
Позволяет инкапсулировать сложную логику запросов, используя EntityManager или JdbcTemplate.
// 1. Объявляем кастомный интерфейс
public interface UserRepositoryCustom {
List<User> findUsersByComplexBusinessRule();
}
// 2. Реализуем его. Имя класса должно быть {ИмяОсновногоРепозитория}Impl
public class UserRepositoryImpl implements UserRepositoryCustom {
@PersistenceContext
private EntityManager entityManager;
@Override
public List<User> findUsersByComplexBusinessRule() {
// Реализация с использованием Criteria API, QueryDSL или нативного SQL
return ...;
}
}
// 3. Основной репозиторий расширяет и JpaRepository, и кастомный интерфейс
public interface UserRepository extends JpaRepository<User, Long>, UserRepositoryCustom {}
Рекомендации по выбору:
- Query Creation: Для простых, декларативных запросов.
@Query(JPQL): Для большинства сложных запросов, связанных с сущностями. Безопаснее и переносимее нативного SQL.@Query(native): Когда необходим специфичный синтаксис СУБД или сложные SQL-оптимизации.- Кастомная реализация: Для максимальной гибкости, когда запрос невозможно выразить через JPQL или требуется работа с низкоуровневыми API.