8.3 @Query 어노테이션

김찬미·2024년 6월 20일
0

@Query 어노테이션 사용하기

데이터베이스에서 값을 가져올 때는 앞 절에서 소개한 것처럼 메서드의 이름만으로 쿼리 메서드를 생성할 수도 있고 이번 절에서 살펴볼 @Query 어노테이션을 사용해 직접 JPQL을 작성할 수도 있다.

JPQL을 사용하면 JPA 구현체에서 자동으로 쿼리 문장을 해석하고 실행하게 된다. 만약 데이터베이스를 다른 데이터베이스로 변경할 일이 없다면 직접 해당 데이터베이스에 특화된 SQL을 작성할 수 있다.

1) 리포지토리에 메서드 추가하기

먼저 기본적인 JPQL을 사용해 상품정보를 조회하는 메서드를 리포지토리에 추가한다.

@Query("SELECT p FROM Product AS p WHERE p.name = ?1")
List<Product> findByName(String name);
  • 1번 줄: @Query 어노테이션을 사용해 JPQL 형식의 쿼리문 작성
    • FROM 뒤에서 엔티티 타입을 지정하고 별칭 생성 (AS는 생략 가능)
    • WHERE 절에서는 SQL과 마찬가지로 조건을 지정

위 예제의 조건문에서 사용한 ?1은 파라미터를 전달받기 위한 인자에 해당한다. 하지만 이 같은 방식을 사용할 경우 파라미터의 순서가 바뀌면 오류가 발생할 가능성이 있어 @Param 어노테이션을 사용하는 것이 좋다.

2) @Param 어노테이션 사용하기

@Query("SELECT p FROM Product p WHERE p.name = :name")
List<Product> findByNameParam(@Param("name") String name);

이처럼 파라미터를 바인딩하는 방식으로 메서드를 구현하면 코드의 가독성이 높아지고, 파라미터의 순서가 바뀌어도 오류가 발생하지 않아 유지보수가 수월해진다.

1,2) Hiberate에서 생성되는 쿼리

앞에서 살펴본 두 예제는 Hibernate에서 다음과 같이 동일한 쿼리를 생성해서 실행한다.

Hibernate: 
    select
        product0_.number as number1_0_,
        product0_.created_at as created_2_0_,
        product0_.name as name3_0_,
        product0_.price as price4_0_,
        product0_.stock as stock5_0_,
        product0_.updated_at as updated_6_0_ 
    from
        product product0_ 
    where
        product0_.name=?

3) 원하는 컬럼의 값만 추출하기

@Query를 사용하면 엔티티 타입이 아니라 원하는 칼럼의 값만 추출할 수 있다.

@Query("SELECT p.name, p.price, p.stock FROM Product p WHERE p.name = :name")
List<Object[]> findByNameParam2(@Param("name") String name);

이처럼 SELECT에 가져오고자 하는 칼럼을 지정하면 된다. 이때 메서드에서는 Object 배열의 리스트 형태로 리턴 타입을 지정해야 한다.

3) Hiberate에서 생성되는 쿼리

위 메서드를 호출했을 때 생성되는 쿼리는 다음과 같다.

Hibernate: 
    select
        product0_.name as col_0_0_,
        product0_.price as col_1_0_,
        product0_.stock as col_2_0_ 
    from
        product product0_ 
    where
        product0_.name=?
profile
백엔드 개발자

0개의 댓글

관련 채용 정보