[SpringData] 쿼리 메서드 기능 3가지

KMS·2022년 4월 25일
0

SpringData

목록 보기
2/9

SpringData에서는 쿼리를 메서드를 호출해서 실행 할 수 있는 방법이 3가지가 있습니다.
1. 메서드 이름으로 쿼리 생성
2. 메서드 이름으로 @NamedQuery 호출
3. 메서드에 @Query 애노테이션으로 쿼리 정의

1. 메서드 이름으로 쿼리 생성

JpaRepository<Entity, ID>를 상속 받는 Spring Data 인터페이스에는 단순히 메서드 이름만으로도 관례에 맞춰서 Spring이 메서드 이름을 쿼리문으로 변형 시켜서 처리합니다.
ex:

List<Member> findTop2ByUsernameAndAgeGreaterThan(String username, int age);

해당 메서드를 선언하고 호출하면, "SELECT *FROM member m WHERE m.username = username AND m.age = age LIMIT 2;" 쿼리문으로 변형 되어서 처리 됩니다.

주의할 점:
1. 메서드 이름이 꼭 엔티티의 속성 값과 일치 해야 합니다. 예를 들어, Member 엔티티에 username이라는 속성이 있을때, 메서드 이름을 findByUsername() 대신 findByUserName(), findByUsername2() 등등 속성 값과 일치하지 않으면 쿼리 생성에 오류가 생깁니다. 속성 값에서 첫 글자만 대문자로 바꾼 이름만 메서드 이름으로 사용 가능합니다.
2. 쿼리문이 복잡해질수록 해당 방법을 사용하기 까다로워질 수 있습니다. 그렇기 때문에, 해당 방법은 간단한 쿼리문일 경우 사용하는게 적합합니다.

2. 메서드 이름으로 @NamedQuery 호출

JpaRepository<Entity, ID>를 상속 받는 Spring Data 인터페이스에서 해당 엔티티의 @NamedQuery를 메서드로 호출해서 사용 할 수 있으며, 순수 JPA에서는 setParameter()로 파라미터 값들을 설정 해줬지만, Spring Data에서는 @Param 애노테이션으로 파라미터 값을 설정 해줄 수 있습니다.
(@NamedQuery에 대한 내용은 JPA Basics를 참고해 주세요. https://velog.io/@k_ms1998/JPA-JPQL-NamedQuery)

	@Query(name = "Member.findByUsername")
    List<Member> findByUsername(@Param("username") String username);

이때, @Query 애너테이션을 생략해도 @NamedQuery가 호출이 가능합니다. 왜냐하면, 애플리케이션 로딩 시점에서 Spring이 Entity+메서드 이름의 조합으로 된 @NamedQuery가 있는지 확인을 합니다. 해당 예제는 Member 엔티티에서 findByUsername 메서드 이름이기 때문에, Member.findByUsername 이름을 가진 @NamedQuery가 있는지 확인을 합니다.
만약 일치하는 @NamedQuery가 없으면, 위에서 봤던 메서드 이름으로 쿼리를 생성합니다.

3. 메서드에 @Query 애노테이션으로 쿼리 정의

실무에서 가장 많이 사용 되는 방법으로, @Query 애노테이션가 붙혀진 메서드가 호출 되면, @Query에 작성된 쿼리가 실행되도록 하는 방법입니다.

	@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);

findUser(username, age) 메서드를 호출하면 @Query에 있는 쿼리문이 실행됩니다. 복잡한 쿼리도 실행이 가능하며, DTO도 같이 사용이 가능합니다.

@Query("select new study.datajpa.repository.dto.MemberDTO(m.username, m.age, m.team) from Member m")
    List<MemberDTO> findUsernameAgeTeamnameList(); //Member들의 username만 반환하기```
profile
Student at Sejong University Department of Software

0개의 댓글