* @Query 어노테이션
- 일반적인 경우 간단한 처리만 쿼리 메소드를 이용하고 나머지는 @Query를 많이 이용한다.
- @Query의 경우 메소드의 이름과 상관없이 메소드에 추가한 어노테이션을 통해서 원하는 처리가 가능하다.
- @Query의 value는 JPQL로 작성되는데 흔희 객체지향 쿼리라고 불리는 구문들이다.
- 필요한 데이터만 선별적으로 추출하는 기능 가능
- 데이터베이스에 맞는 순수한 SQL을 사용
- SELECT가 아닌 DML을 처리하는 기능(@Modifying과 함께 사용)
- 객체지향 쿼리는 테이블 대신에 엔티티 클래스를 이용하고, 테이블 컬럼 대신에 클래스에 선언된 필드를 이용해서 작성한다.
@Query("select m from Memo m order by m.mno desc")
List<Memo> getListDesc();
* @Query의 파리미터 바인딩
- '?1, ?2'와 1부터 시작하는 파라미터의 순서를 이용하는 방식
- ':xxx'와 같이 ':파라미터 이름'을 활용하는 방식
- ':#{ }'과 같이 자바 빈 스타일을 이용하는 방식
@Query("Update Memo m SET m.memoText = :memoText WHERE m.mno = :mno ")
int updateMemoText(@Param("mno")Long mno, @Param("memoText")String memoText);
@Query("update Memo m set m.memoText = :#{#param.memoText} where m.mno = :#{#param.mno} ")
int updateMemoText(@Param("param") Memo memo);
* @Query와 페이징 처리
- 리턴 타입을 Page<엔티티>로 지정하는 경우에는 count를 계산할 수 있는 쿼리가 필수적이다.
- @Query를 이용할 때는 별도의 countQuery라는 속성을 적용해주고 Pageable 타입의 파라미터를 전달하면 된다.
@Query(value = "SELECT m FROM Memo m WHERE m.mno > :mno",
countQuery = "SELECT count(m) FROM Memo m where m.mno > :mno")
Page<Memo> getListWithQuery(Long mno, Pageable pageable);
* Object[] 리턴
- 쿼리 메소드의 경우에는 엔티티 타입의 데이터만을 추출하지만, @Query를 이용하는 경우에는 현재 필요한 데이터만을 Object[]의 형태로 선별적으로 추출할 수 있다.
- JOIN이나 GROUP BY 등을 이용하는 경우가 종종 있는데, 이러한 경우에는 적장한 엔티티 타입이 존재하지 않는 경우가 많기 때문에 이런 상황에서 유용하게 Object[] 타입을 리턴 타입으로 지정할 수 있다.
@Query(value = "SELECT m.mno, m.memoText, CURRENT_DATE FROM Memo m WHERE m.mno > :mno",
countQuery = "SELECT count(m) FROM Memo m WHERE m.mno > :mno")
Page<Object[]> getListWithQueryObject(Long mno, Pageable pageable);
* Native SQL 처리
- @Query의 강력한 기능은 데이터베이스 고유의 SQL 구문을 그대로 활용하는 것이다.
- JPA 자체가 데이터베이스에 독립적으로 구현 가능하다는 장점을 잃어버리지만 경우에 따라서는 복잡한 JOIN 구문 등을 처리하기 위해서 사용한다.
@Query(value = "SELECT * FROM memo WHERE mno > 0", nativeQuery = true)
List<Object[]> getNativeResult();