스프링 데이터 JPA가 제공하는 기능 (사용 순위)
- @Query 어노테이션을 사용해서 repository interface에 쿼리 직접 정의
- 메소드 이름으로 쿼리 생성 (메서드 이름에 파라매터 많아지면 지저분)
- 메소드 이름으로 JPA NamedQuery 호출
1. @Query, 리포지토리 메소드에 쿼리 정의하기
//member repository
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);
}
- @org.springframework.data.jpa.repository.Query 어노테이션을 사용
- 실행할 메서드에 정적 쿼리를 직접 작성하므로 이름 없는 Named 쿼리라 할 수 있음
- 복잡한 JPQL도 직접 써주니까 메서드 명이 간략
- 애플리케이션 실행 시점에 문법 오류를 발견할 수 있음(매우 큰 장점!)
- JPQL을 repo interface에 바로 적을 수 있음.
2. 메소드 이름으로 쿼리 생성
순수 JPA
// 순수 JPA repository
public List<Member> findByUsernameAndAgeGreaterThan(String username, int age) {
return em.createQuery("select m from Member m where m.username = :username and m.age > :age")
.setParameter("username", username)
.setParameter("age", age)
.getResultList();
}
스프링 데이터 JPA
// 스프링 데이터 JPA repository
public interface MemberRepository extends JpaRepository<Member, Long> { // <entity, id type>
List<Member> findByUsernameAndAgeGreaterThan(String username, int age);
}
테스트 코드는 동일
// 순수 JPA 테스트코드
@Test
public void findByUsernameAndAgeGreaterThan() {
Member m1 = new Member("AAA", 10);
Member m2 = new Member("AAA", 20);
memberJpaRepository.save(m1);
memberJpaRepository.save(m2);
List<Member> result = memberJpaRepository.findByUsernameAndAgeGreaterThan("AAA", 15);
assertThat(result.get(0).getUsername()).isEqualTo("AAA");
assertThat(result.get(0).getAge()).isEqualTo(20);
assertThat(result.size()).isEqualTo(1);
}
- find_ _ _By : _ _ _쓰는 것은 선택이며 내가 이 메서드가 뭔지 알 수 있도록 도와주는 역할 (jpa는 모름)
- 쿼리 메소드 필터 조건 : https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation (스프링 데이터 JPA 공식 문서 참고)
- 이 기능은 엔티티의 필드명이 변경되면 인터페이스에 정의한 메서드 이름도 꼭 함께 변경해야 함. 그렇지 않으면 애플리케이션을 시작하는 시점에 오류가 발생. (이렇게 애플리케이션 로딩 시점에 오류를 인지할 수 있는 것이 스프링 데이터 JPA의 매우 큰 장점)
- 실무에서는 메소드 이름으로 쿼리 생성 기능은 파라미터가 증가하면 메서드 이름이 매우 지저분해진다. 따라서 @Query 기능을 자주 사용하게 된다.
3. JPA NamedQuery
엔티티 위에 NamedQuery를 생성해두면
// entity
@Entity
@NamedQuery(
name="Member.findByUsername",
query="select m from Member m where m.username = :username")
public class Member {
...
}
1. 스프링 데이터 JPA로 NamedQuery를 사용하는 방법과
// member repository
@Query(name = "Member.findByUsername")
List<Member> findByUsername(@Param("username") String username);
2. 스프링 데이터 JPA로 Named 쿼리 호출하는 방법이 있다.
// member repository
public interface MemberRepository extends JpaRepository<Member, Long> { //** 여기 선언한 Member 도메인 클래스
List<Member> findByUsername(@Param("username") String username);
}
- @Query 를 생략하고 메서드 이름만으로 Named 쿼리를 호출할 수 있다.
- 애플리케이션 실행 시점에 문법 오류를 발견할 수 있음(매우 큰 장점!)
'Spring boot > 스프링 데이터 JPA' 카테고리의 다른 글
외래키 참조 쿼리 비교(findByMemberId, findByMember) (0) | 2022.09.12 |
---|---|
[spring boot] 벌크성 수정 쿼리 (0) | 2022.01.25 |
[spring boot] 페이징과 정렬 (0) | 2022.01.24 |
[spring boot] 반환 타입 (0) | 2022.01.21 |