Ответ
Spring Data JPA предлагает несколько способов для определения кастомных запросов.
1. Использование аннотации @Query (JPQL или SQL):
@Repository
public interface BookRepository extends JpaRepository<Book, Long> {
// JPQL-запрос (работает с сущностями)
@Query("SELECT b FROM Book b WHERE b.publicationYear > :year")
List<Book> findBooksPublishedAfter(@Param("year") int year);
// Нативный SQL-запрос (работает напрямую с таблицами)
@Query(value = "SELECT * FROM books WHERE title ILIKE %:keyword%", nativeQuery = true)
List<Book> searchByTitleKeyword(@Param("keyword") String keyword);
// Модифицирующий запрос (UPDATE/DELETE) требует @Modifying
@Modifying
@Query("UPDATE Book b SET b.price = b.price * 1.1 WHERE b.category = :category")
int increasePriceByCategory(@Param("category") String category);
}
2. Query by Example (QBE):
- Динамический запрос на основе экземпляра-прототипа сущности.
Book probe = new Book(); probe.setAuthor("Tolkien"); Example<Book> example = Example.of(probe); List<Book> result = repository.findAll(example);
3. QueryDSL / Specifications:
- Specifications: Позволяют строить типобезопасные предикаты для динамических запросов.
- QueryDSL: Генерирует Q-классы и предоставляет fluent API для сложных запросов. Часто используется вместе с
JPAQueryFactory.