JpaRepository에서는 기본적인 쿼리들을 미리 만들어 제공하지만 만약 복잡한 쿼리가 필요하다면 @Query를 사용해 쿼리를 직접 작성할 수 있다.
@Query("SELECT COALESCE(MAX(commentSn), 0) " +
"FROM Comment " +
"WHERE boardSn = :boardSn")
Long findMaxCommentSnByBoardSn(Long boardSn);
@Query 어노테이션에 문자열로 쿼리를 작성하면 된다. 동적으로 작성하고 싶은 내용은 콜론(:)을 사용해 메서드의 파라미터명을 작성하면 된다. 쿼리를 조회하여 반환되는 값은 메서드의 반환 타입으로 작성하면 된다.
주의해야할 점은, @Query에 작성하는 쿼리문의 테이블명과 컬럼명은 실제 데이터베이스에서의 테이블명과 컬럼명이 아닌 엔티티의 클래스명과 필드명을 따른 다는 점이다.
위 @Query를 예시로 들면, 엔티티 클래스의 이름은 'Comment'이고 필드명은 'commentSn'과 'boardSn'이다. 하지만 실제 데이터베이스에서 테이블명은 'comment'이고 필드명은 각각 'comment_sn', 'board_sn'이다.
@Entity
@Table(name = "comment")
@IdClass(CommentKey.class)
public class Comment {
@Id
@Column(name = "board_sn")
private Long boardSn;
@Id
@Column(name = "comment_sn")
private Long commentSn;
...
}
또한 기존 쿼리문에서 전체 컬럼을 의미하던 별표(아스타리스크; *)는 SELECT 절에서 사용할 수 없다. 대신 FROM 절에서 테이블에 대해 별칭(Alias)을 설정하여 이를 별표 대신 사용할 수 있다.
@Query(
"SELECT p " +
" FROM Product p " +
" WHERE p.number = :number "
)
Product findByNumber(Long number);
만약 'Validation failed for query for method public abstract ~' 과 같은 에러가 발생할 경우, 쿼리를 Native Query로 실행하는 옵션을 추가해주면 해결할 수 있다.
단, Native Query 옵션을 사용할 경우 쿼리문을 JPA가 아닌 순수 쿼리문으로 해석한다. 그러므로 테이블명이나 컬럼명을 위에서 설명한 방식이 아닌 기존에 데이터베이스에서 사용하던 이름으로 사용해야 한다.
@Query(
value =
"SELECT * " +
" FROM product p " +
" WHERE p.number = :number ",
nativeQuery = ture
)
Product findByNumber(Long number);
'Java > Spring Boot' 카테고리의 다른 글
[Spring Boot] JSP 사용하기 (0) | 2023.04.12 |
---|---|
[Spring Boot] JpaRepository의 쿼리 메서드 자동 구현 (0) | 2023.04.11 |
[Spring Boot] JPA의 Entity에서 1대N 관계 설정 (0) | 2023.04.10 |
[Spring Boot] JPA의 복합키 (0) | 2023.04.09 |
[Spring Boot] Controller 예외처리 (0) | 2023.04.09 |