Spring & Spring Boot

[Spring] @Query 사용법 및 예시코드 (JPA에서 쿼리를 직접쓰는 방법 !)

WOOOOJI 2023. 3. 16. 14:04

Spring Data JPA에서 제공하는 쿼리 메소드 기능 중 하나인

@Query 어노테이션에 대해 알아보자 !


@Query

복잡한 조건을 요구하는 경우에 AND, OR, JOIN 등을 JPA 메소드를 통해서 사용할려면 불편할 때가 많고, 무엇보다 성능 저하 우려가 있기 때문에 직접 쿼리문을 짜는게 효율적이다. 그때 사용하는게 바로 @Query이다. (Named Query 같은 것도 있지만 매개변수가 많아지면 너무 길어져서 지저분 하다....)

 

특징

  • JPQL을 사용한다 (객체지향 쿼리문. 테이블 대신 Entity클래스를 사용하고 컬럼 대신 필드를 사용한다)
  • 직접 쿼리문을 작성하기에 복잡한 작업이 가능하다
  • INSERT, UPDATE, DELETE 과 같이 SELECT가 아닌 DML들은 @Modifying과 함께 써야한다. (추가로 @Transaction을 쓸 수 있다)
  • 필요한 데이터만 골라 가져올 수 있다.

 


UserRepository.Java

public interface UserRepository extends JpaRepository<User, Long> {
    @Query("SELECT u FROM User u WHERE u.id = :id")
    Optional<User> findByCustomeId(@Param("id") Long id);

@Query에 쓴걸 보면 SELECT절이 어색할 수 있는데, 앞서 말했던 특징을 보면 알 수 있다. JPQL이라는 객체 지향 쿼리문을 사용하기에 테이블명을 쓰는 대신에 Entity클래스를 쓰고 컬럼 대신 필드명을 쓴다.

쿼리문이 정확하게 잘 실행된걸 확인 할 수 있다 !


만약 필드 하나만 선택하고 싶다면?

    @Query("SELECT u.id FROM User u WHERE u.id = :id")

엔티티 전체인 u를 SELECT 하는게 아닌 u안에 있는 id값만 SELECT 하면 되는것이다.

 

 

 


UPDATE, DELETE같은 변경사항이 생기는 쿼리는?

    @Transactional
    @Modifying
    @Query("update User u set u.name = :name where u.id = :id")
    void updateName(@Param("id") Long id , @Param("name") String name);

다음과 같은 구성을 가지게 된다. 쿼리는 크게 달라진게 없어보이지만 2가지 어노테이션이 추가된걸 확인 할 수 있다.

 

  • @Transactional
    • INSERT, DELETE, UPDATE 작업 중 오류가 발생하면 모든 작업들을  rollback한다.
    • 이전에 모든 작업이 성공적이었더라도 어떤 작업에서 오류가 나면 모두 rollback 된다.
  • @Modifying
    • @Query를 통해 INSERT, DELETE, UPDATE쿼리를 쓰게 될때 무조건 사용해야하는 어노테이션
    • JpaRepository에서 제공하는 기본 메소드 등은 적용되지 않는다.

 


 

SQL에 익숙하시다면 매우매우 쉬운 사용방법입니다.
하지만 그렇지 않다면 쿼리문 직접 쓰는거 자체가 고통? 일수도 있습니다 :(

오늘도 슬기로운 코딩 생활 하시길 바라며 !
언제나 피드백과 잘못 기재된점에 대한 댓글들을 환영입니다 :)
728x90