쿼리 메소드 기능은 스프링 데이터 JPA가 제공하는 특별한 기능이다. 크게 3가지 기능이 있다.
- 메소드 이름으로 쿼리 생성
- 메소드 이름으로 JPA NamedQuery 호출
- @Query 어노테이션을 사용하여 레포지토리 인터페이스에 쿼리 직접 정의
List<Member> findByUsernameAndAge(String username, int age);
인터페이스에 정의한 findByUsernameAndAge() 메소드를 실행하면 스프링 데이터 JPA는 메소드 이름을 분석하여 JPQL을 생성하고 실행한다. 생성된 JPQL은 다음과 같다.
select m from Member m where m.username = ?1 and m.age = ?2
@Entity
@NamedQuery( name = "Member.findByUsername"
, query = "select m from Member m where m.username = :username" )
public class Member { ... }
JPA를 직접 사용해서 Named 쿼리 호출
List<Member> findByUsername(@Param("username") String username);
public interface MemberRepository extends JpaRepository<Member, Long> {
@Query("select m from Member m where m.username = :username and m.age = :age")
List<Member> findUser(@Param("username") String username, @Param("age") int age);
// 단순 값 하나를 조회
@Query("select m.username from Member m")
List<String> findUsernameList();
// DTO로 직접 조회
@Query("select new me.kyeongho.dto.MemberDto(m.id, m.username, t.name) from Member m join m.team t")
List<MemberDto> findMemberDto();
// 네이티브 SQL로 조회
@Query(value = "SELECT * FROM MEMBER WHERE USERNAME = ?0", nativeQuery = true)
Member findByUsername(String username);
}
이중에서 가장 익숙한 방법인 3번을 사용하겠다.
일단 도메인부터 보자면,
@Builder
@ToString(exclude = "ebBookMst")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class EbEbookCd extends BaseTimeEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int seq;
@Column(length = 11, nullable = false, columnDefinition="int(11) comment '도서(eb_book_mst) 테이블의 PK'" )
private Long bookSeq;
...
@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "bookSeq", referencedColumnName="bookSeq", insertable=false, updatable=false)
private EbBookMst ebBookMst;
}
그리고, 리포지토리는 아래와 같이 구성했다.
@Repository
public interface EbEbookCdHistRepository extends JpaRepository<EbEbookCdHist,Integer> {
@Query("select h from EbEbookCdHist h left join fetch h.mst where h.seq = :seq")
Optional<EbEbookCdHist> findBySeq(@Param("seq") Integer seq);
}
출처
https://medium.com/jaehoon-techblog/simpleblog-%EA%B0%9C%EB%B0%9C-%EC%9D%BC%EC%A7%80-4-55a8d2a8604