Sobes.tech
Назад к вопросам
Junior — Middle
51

Какие способы задания запросов с использованием аннотации @Query доступны в вашем фреймворке?

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

@Query позволяет явно задать запрос вместо вывода его из имени метода. Обычно используют либо JPQL, либо нативный SQL. Также можно подставлять параметры по имени или по позиции и, при необходимости, получать модифицирующие запросы через @Modifying.

Определение:

@Query — это аннотация в Spring Data JPA, с помощью которой в репозитории задают запрос вручную. Она полезна, когда метод сложно выразить через производное имя, когда нужен более точный контроль над запросом или когда требуется использовать специфичные конструкции JPQL или SQL.

Основные способы задания запроса:

  • JPQL-запрос через @Query без nativeQuery = true
  • нативный SQL-запрос через @Query(nativeQuery = true)
  • запросы с параметрами: именованными :name или позиционными ?1
  • модифицирующие запросы UPDATE, DELETE в сочетании с @Modifying
  • при необходимости — пагинация, сортировка и проекции, если фреймворк это поддерживает в данном типе запроса

Пример использования:

public interface UserRepository extends JpaRepository<User, Long> {

    // JPQL
    @Query("select u from User u where u.email = :email")
    Optional<User> findByEmail(@Param("email") String email);

    // Нативный SQL
    @Query(value = "select * from users where status = ?1", nativeQuery = true)
    List<User> findAllByStatus(String status);

    // Обновление данных
    @Modifying
    @Query("update User u set u.active = false where u.lastLogin < :date")
    int deactivateOldUsers(@Param("date") LocalDate date);
}

Пояснение кода:

В первом методе используется JPQL: запрос работает не с таблицей users, а с сущностью User и ее полями. Параметр :email связывается с аргументом метода через @Param.

Во втором методе используется нативный SQL: здесь уже пишется запрос к таблице users, а не к сущности. Параметр передается по позиции через ?1.

В третьем методе запрос изменяет данные, поэтому нужна аннотация @Modifying. Метод возвращает количество затронутых строк, что удобно для проверки результата обновления.

Если тема не про код, код все равно уместен, потому что @Query — это именно про задание запросов, и на примере хорошо видно разницу между JPQL, native SQL и модифицирующими запросами.

Ключевые моменты:

  • @Query используется, когда производного метода недостаточно или запрос нужен в точном виде.
  • Без nativeQuery = true обычно пишут JPQL, где используются сущности и их поля.
  • С nativeQuery = true пишут SQL, ориентированный на конкретную БД и таблицы.
  • Параметры можно передавать именованно (:name) или позиционно (?1).
  • Для UPDATE и DELETE обычно нужна @Modifying.
  • Выбор между JPQL и SQL зависит от задачи: JPQL более переносим, SQL дает больше контроля над БД.