✅ 메소드 이름으로 쿼리 생성 ✅ @NamedQuery ✅ @Query
Spring Data JPA로 쿼리를 생성하는 방법들을 알아보자.
메소드의 이름만으로 관례적으로 기능을 자동 구현해준다.
- 엔티티의 필드명이 변경되면 인터페이스에 정의한 메서드 이름도 꼭 함께 변경해야 한다. (그렇지 않으면 애플리케이션을 시작하는 시점에 오류가 발생)
- 이렇게 애플리케이션 로딩 시점에 오류를 인지할 수 있는 것이 스프링 데이터 JPA의 매우 큰 장점
Document (스프링 데이터 JPA - query-creation) 를 참고하면 아래보다 더 많은 쿼리를 확인, 활용 할 수 있다.
public interface MemberRepository extends JpaRepository<Member, Long> {
List<Member> findByUsernameAndAgeGreaterThan(String username, int age);
}
@NamedQuery 어노테이션으로 쿼리에 이름을 부여 및 정의하여 호출, 사용한다.
- 엔티티에 쿼리를 선언해줘야 하는 등 불편함 때문에 실무에서는 잘 사용하지 않는다고 함
- @NamedQuery 도 애플리케이션 로딩 시점에 오류를 인지할 수 있는 장점이 있다.
@Entity
@NamedQuery(
name="Member.findByUsername",
query="select m from Member m where m.username = :username"
)
public class Member {
...
}
public interface MemberRepository extends JpaRepository<Member, Long> {
@Query(name = "Member.findByUsername") // 선언을 하지 않아도 spring data jpa가 알아서 관례상 찾아 넣어주긴 함
List<Member> findByUsername(@Param("username") String username);
}
레포지토리 메소드에 쿼리를 직접 정의하는 방법
- 실무에서 @NamedQuery 보다는 @Query 를 사용해서 레포지토리 메소드에 쿼리를 직접 정의한다.
- @Query 도 애플리케이션 로딩 시점에 오류를 인지할 수 있는 장점이 있다.
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);
}
public interface MemberRepository extends JpaRepository<Member, Long> {
@Query("select m.username from Member m")
List<String> findUsernameList();
}
public interface MemberRepository extends JpaRepository<Member, Long> {
@Query("select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) " + "from Member m join m.team t")
List<MemberDto> findMemberDto();
}
@Data // getter, setter 다 들어가 있으므로 웬만하면 안쓰는게 좋음
public class MemberDto {
private Long id;
private String username;
private String teamName;
public MemberDto(Long id, String username, String teamName) {
this.id = id;
this.username = username;
this.teamName = teamName;
}
}