Вопрос направлен на проверку умения выходить за рамки стандартных CRUD-операций и создавать специализированные запросы к БД с помощью Hibernate.
Кастомные запросы в Hibernate создаются primarily с помощью JPQL (язык запросов, похожий на SQL, но работающий с сущностями) или нативного SQL. JPQL-запросы определяются с помощью аннотации @Query прямо в репозитории. Нативные SQL-запросы используются для сложных, специфичных для БД операций, но они привязывают код к конкретной СУБД.
Когда встроенных методов Spring Data JPA (например, findByFirstName) недостаточно, используются кастомные запросы. Hibernate и Spring Data JPA предоставляют для этого несколько основных способов.
Способы создания кастомных запросов:
JPQL (Java Persistence Query Language):
Это объектно-ориентированный язык запросов. Вместо таблиц и колонок вы используете имена сущностей и их полей.
Записывается с помощью аннотации @Query в интерфейсе-репозитории.
public interface UserRepository extends JpaRepository<User, Long> {
// Поиск пользователей по имени (JPQL)
@Query("SELECT u FROM User u WHERE u.firstName = :name")
List<User> findUsersByName(@Param("name") String name);
// Более сложный пример с JOIN
@Query("SELECT u FROM User u JOIN u.orders o WHERE o.total > :amount")
List<User> findUsersWithOrdersGreaterThan(@Param("amount") BigDecimal amount);
}Нативный SQL (Native Queries):
Используется, когда нужна специфичная для базы данных функциональность или очень сложный запрос, который невозможно выразить в JPQL.
Для этого в аннотации @Query устанавливается атрибут nativeQuery = true.
public interface UserRepository extends JpaRepository<User, Long> {
@Query(value = "SELECT * FROM users u WHERE u.email LIKE '%gmail.com'", nativeQuery = true)
List<User> findUsersWithGmail();
}Вывод:
JPQL является предпочтительным способом для большинства случаев, так как он переносим между разными СУБД. Нативный SQL следует использовать осторожно, только когда это действительно необходимо.