코딩마을방범대

[Java] @Query 어노테이션 본문

💡 백엔드/Java

[Java] @Query 어노테이션

신짱구 5세 2024. 7. 23. 09:03
728x90

 

 

JPA가 제공하는 쿼리 메서드는 단순한 CRUD 기능이 가능하여 편리함을 제공하기는 하지만,

복잡한 조건을 처리해야하는 경우에는 한계가 있다.

이럴 때 사용하는 것이 @Query 어노테이션이다.

 

 

JPA 쿼리 메서드의 정의는 아래 링크를 통해 확인 가능하다.

 

JPA Query Methods :: Spring Data JPA

As of Spring Data JPA release 1.4, we support the usage of restricted SpEL template expressions in manually defined queries that are defined with @Query. Upon the query being run, these expressions are evaluated against a predefined set of variables. Sprin

docs.spring.io

 

 

 

 

 


 

 

 

 

 

 

@Query

 

기본적인 CRUD 메서드 외에 추가적인 쿼리가 필요한 경우 사용할 수 있다.

JPQL(Java Persistence Query Language) 또는 네이티브 SQL을 사용하여 쿼리를 정의할 수 있다.

 

 


 

@Query 어노테이션의 속성

속성명 설명
value JPQL 또는 네이티브 SQL 쿼리를 정의함
nativeQuery true로 설정하면 네이티브 SQL 쿼리를 사용할 수 있음
countQuery 페이징 처리를 위한 카운트 쿼리를 별도로 정의할 수 있음
네이티브 SQL이란?
특정 데이터베이스 시스템에 최적화된 SQL 쿼리를 의미
데이터베이스 벤더(예: Oracle, MySQL, PostgreSQL 등)가 제공하는 고유한 SQL 문법과 기능을 사용하는 것

장점: 데이터베이스 고유 기능을 활용할 수 있어 복잡한 쿼리를 작성할 수 있음
단점: 데이터베이스에 종속적이므로 데이터베이스를 변경할 경우 쿼리를 수정해야 함

 


 

 

@Query와 JpaRepository의 차이점

  @Query JpaRepository
쿼리 작성 방식 JPQL(Java Persistence Query Language) 또는 SQL을 직접 작성하여 쿼리를 정의할 수 있음 메서드 이름 규칙을 따라 쿼리를 자동으로 생성함
쿼리 복잡성 복잡한 쿼리를 작성할 수 있음 상대적으로 단순함
쿼리 최적화 직접 작성한 쿼리를 최적화할 수 있음 JPA 구현체가 최적화함
쿼리 재사용성 정의한 쿼리를 다른 메서드에서 재사용할 수 있음 재사용하기 어려움
쿼리 가독성 JPQL 또는 SQL을 직접 작성하므로 쿼리의 가독성이 높음 가독성이 상대적으로 낮음

 

 


 

SQL과 JPQL의 차이점

  SQL JPQL
대상 객체 데이터베이스의 테이블 엔티티 객체
추상화 수준 데이터베이스의 물리적인 구조에 의존적 객체 지향적인 추상화 수준을 가지고 있어 데이터베이스의 물리적인 구조에 독립적
쿼리 작성 방식 테이블 이름, 컬럼 이름 등을 직접 명시해야 함 엔티티 이름과 엔티티의 필드 이름을 사용하여 쿼리를 작성
데이터 타입 데이터베이스의 데이터 타입을 사용 자바 객체의 데이터 타입을 사용
쿼리 실행 과정 데이터베이스에 직접 쿼리를 전달하여 실행 JPA 구현체가 JPQL을 SQL로 변환하여 데이터베이스에 전달



 

 

 


 

 

 

 

 

 

사용 예제

 

1. 기본적인 JPQL 쿼리 사용

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    @Query("SELECT u FROM User u WHERE u.email = :email")
    User findByEmail(@Param("email") String email);
}

 

 


 

2. 복잡한 쿼리 사용

@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
    @Query("SELECT o FROM Order o " +
           "WHERE o.customer.name = :name " +
           "AND o.status = :status " +
           "ORDER BY o.createdDate DESC")
    List<Order> findOrdersByCustomerNameAndStatus(@Param("name") String name, @Param("status") OrderStatus status);
}

 

 


 

3. 네이티브 SQL 사용

네이티브 SQL 쿼리에서는 순서 기반 파라미터 바인딩을 사용한다.

즉, 물음표 ?1, ?2 등으로 파라미터를 표현하고, 메서드 파라미터 순서대로 바인딩된다.

(네이티브 SQL 쿼리에서는 @Param 어노테이션을 사용할 필요가 없음)

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    @Query(value = "SELECT * FROM users WHERE email = ?1", nativeQuery = true)
    User findByEmail(String email);
}

 

 


 

4. 파라미터 바인딩

@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
    @Query("SELECT p FROM Product p WHERE p.name LIKE %:keyword%")
    List<Product> searchByName(@Param("keyword") String keyword);
}

 

 

 

 

 


참고사이트

@Query 어노테이션

 

 

728x90