🤔 스프링 데이터 JPA 의 공통 인터페이스 기능이 아닌, 특정 도메인에 특화된 기능을 사용하고 싶을 때는 어떻게 처리하면 좋을까? 예를 들어, findByUsername()
과 같이 회원의 이름을 기준으로 조회하고자 하는 경우 말이다.
이를 해결하기 위해 스프링 데이터 JPA 에서는 쿼리 메소드라는 기능을 제공한다.
쿼리 메소드 기능 3가지
find...By
, read...By
, query...By
, get...By
By
뒤에는 where 문에 적용될 조건들을 넣으면 된다. (아무것도 안넣으면 전체 조회)...
에는 식별하기 위한 내용(설명)이 들어가도 된다.ex) Optional<Member> findOptionalByUsername(String username);
delete...By
, remove...By
NamedQuery
를 호출할 수 있다."도메인 클래스 + .(점) + 메서드 이름"
으로 Named 쿼리를 찾아서 실행한다.@Query
를 사용해서 리파지토리 메소드에 쿼리를 직접 정의한다. (아래 ③)JPA NamedQuery
처럼 애플리케이션 실행 시점에 문법 오류를 발견할 수 있다. (매우 큰 장점)@Query
기능을 사용해서 메소드 이름을 조금 심플하게 가져가고, 쿼리를 직접 정의해서 주로 사용한다.QueryDSL
을 사용해서 처리한다.
✔️ 참고
@Query
를 통해서, (엔티티 타입이 아닌) 값이나 DTO를 조회하는 방법
단순히 값 하나를 조회
: 조회할 값을 지정하고 반환 타입을 잘 맞춰주면 된다.@Embedded
)도 이 방식으로 조회할 수 있다.DTO로 직접 조회
: DTO로 직접 조회하려면 JPA 의 new
명령어를 사용해야 한다. 그리고 DTO에 조회하고자 하는 데이터를 받는 생성자가 필요하다.파라미터 바인딩
select t from Team t where t.name = ?0
)select t from Team t where t.name = :name
)Collection
타입으로 in
절을 지원한다. )반환 타입
List<Team>
)Team
)Optional<Team>
)null
이 아닌, 빈 컬렉션이 반환된다.null
체크 로직을 작성하는 것은 의미가 없다.null
이 반환된다.Query.getSingleResult()
메서드를 호출한다. 그런데 이 메서드는 조회 결과가 없으면 jakarta.persistence.NoResultException
예외를 발생시키는데, 개발자 입장에서는 다루기가 상당히 불편하다. 따라서, 스프링 데이터 JPA는 단건을 조회할 때 이 예외가 발생하면 예외를 무시하고 대신에 null
을 반환한다.jakarta.persistence.NonUniqueResultException
예외가 발생한다. org.springframework.dao.IncorrectResultSizeDataAccessException
)강의를 듣고 정리한 글입니다. 코드와 그림 등의 출처는 김영한 강사님께 있습니다.