SPRING&BOOT/JPA

@Query 어노테이션 기본 설명

jki09871 2024. 10. 4. 12:00
@Query 어노테이션은 Spring Data JPA에서 JPQL(Java Persistence Query Language) 또는 네이티브 SQL 쿼리를 작성할 때 사용하는 어노테이션이다. 보통은 메서드 이름을 기반으로 쿼리를 자동으로 생성하는데, 복잡한 쿼리나 특정 요구사항이 있는 경우 직접 쿼리를 작성해야 할 때 사용된다.

 

@Query 어노테이션 기본 설명

  • 어노테이션 위치: @Query는 Repository 인터페이스의 메서드 위에 붙인다.
  • 쿼리 타입: JPQL과 네이티브 쿼리 두 가지를 사용할 수 있다. 기본은 JPQL로, JPA 엔티티를 대상으로 하는 쿼리이다. 네이티브 쿼리는 실제 데이터베이스에서 사용하는 SQL 쿼리를 직접 작성할 수 있다.
// 기본 JPQL 예시
@Query("SELECT t FROM Task t WHERE t.weather = :weather")
List<Task> findByWeather(@Param("weather") String weather);

위 코드는 Task라는 엔티티에서 weather라는 필드를 기반으로 데이터를 검색하는 쿼리이다. :weather는 파라미터를 의미하며, @Param을 통해 메서드 인자로 전달된 값을 사용한다.

@Query 문법 구조

1. SELECT 절: 어떤 엔티티(테이블)를 조회할지 지정한다. JPQL에서는 엔티티를 대상으로 쿼리를 작성한다.

SELECT t FROM Task t

 

  • 여기서 Task는 엔티티 이름이며, t는 별칭이다. 즉, Task 엔티티에서 데이터를 조회할 때 t라는 별칭을 사용할 수 있다.

2. WHERE 절: 조건을 지정하는 부분이다. 여기서 쿼리에 사용할 필터링 조건을 정의한다.

WHERE t.weather = :weather

:weather는 파라미터를 의미하며, 메서드 인자에서 값을 전달받아 해당 값을 쿼리에 적용한다. 이런 방식으로 동적 파라미터를 사용할 수 있다.

 

3. @Param 어노테이션: @Param을 사용하여 메서드의 인자와 쿼리의 파라미터를 매칭시킨다.

@Query("SELECT t FROM Task t WHERE t.weather = :weather")
List<Task> findByWeather(@Param("weather") String weather);

여기서 @Param("weather")는 메서드 인자 weather와 쿼리의 :weather 파라미터를 매칭시킨다. 메서드 호출 시 넘겨준 값이 쿼리에서 사용된다.

네이티브 쿼리 사용

가끔 JPQL로는 해결되지 않는 복잡한 쿼리가 있을 때가 있다. 이럴 때 네이티브 SQL을 사용할 수 있다. 네이티브 SQL은 데이터베이스에서 바로 실행되는 쿼리이기 때문에 JPA가 아닌 실제 SQL 문법을 사용한다.

@Query(value = "SELECT * FROM tasks WHERE weather = :weather", nativeQuery = true)
List<Task> findByWeatherNative(@Param("weather") String weather);

여기서 nativeQuery = true를 사용하면 네이티브 SQL로 실행된다. 실제 데이터베이스에 있는 테이블명과 필드명을 직접 사용해야 한다.

여러 조건을 사용한 @Query 예시

@Query는 여러 조건을 조합하여 사용할 수 있다. 예를 들어, 두 가지 조건을 만족하는 데이터를 찾고 싶을 때는 AND 또는 OR을 사용할 수 있다.

@Query("SELECT t FROM Task t WHERE t.weather = :weather AND t.modifiedDate >= :date")
List<Task> findByWeatherAndDate(@Param("weather") String weather, @Param("date") LocalDate date);

 

 

위 예시는 weather 필드와 modifiedDate 필드 모두에 조건을 걸어 데이터를 필터링하는 방법이다. AND는 두 조건이 모두 참일 때만 데이터를 반환한다.

동적 쿼리 사용 (Optional 파라미터)

경우에 따라 파라미터를 선택적으로 사용할 수 있다. 이런 경우는 null 값을 체크하여 동적으로 쿼리를 변경하는 방식이다.

@Query("SELECT t FROM Task t WHERE (:weather IS NULL OR t.weather = :weather) AND (:date IS NULL OR t.modifiedDate >= :date)")
List<Task> searchTasks(@Param("weather") String weather, @Param("date") LocalDate date);

이 예시는 weather와 date 파라미터가 각각 null일 경우 조건을 무시하고, 그렇지 않으면 해당 조건을 적용하는 방식이다. 즉, weather가 없으면 모든 날씨 데이터를, date가 없으면 모든 날짜 데이터를 검색하는 동적 쿼리이다.

결론

@Query 어노테이션은 JPA에서 제공하는 강력한 기능으로, 복잡한 쿼리를 작성할 수 있게 해준다. 기본 메서드 이름으로는 처리하기 어려운 복잡한 로직이나 동적 쿼리를 처리할 때 유용하다. JPQL을 기본으로 하지만, 필요할 때 네이티브 SQL을 사용할 수도 있다. 메서드에 붙여 쿼리를 직접 작성하고, 파라미터를 통해 동적인 데이터 필터링을 구현할 수 있다.

이처럼 @Query는 유연한 쿼리 작성을 가능하게 해주는 매우 중요한 도구이다. 실무에서 다양한 쿼리 요구사항을 만족시키기 위해 자주 사용되는 기능이기 때문에 꼭 익혀두는 것이 좋다.