메소드 이름으로 쿼리 생성
메소드 이름을 분석해서 JPQL 쿼리 실행
예) 이름과 나이름 기준으로 회원을 조회하려면?
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 테스트 코드
@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);
}
스프링 데이터 JPA
public interface MemberRepository extends JpaRepository<Member, Long> {
List<Member> findByUsernameAndAgeGreaterThan(String username, int age);
}
처음 접하고 이렇게 간단하다고? 싶었다.
스프링 데이터 JPA는 메소드 이름을 분석해서 JPQL을 생성하고 실행하기 때문에 가능하다.
스프링 데이터 JPA가 제공하는 쿼리 메소드 기능
- 조회: find...By ,read...By ,query...By get...By
- 예) findHelloBy 처럼 ...에 식별하기 위한 내용(설명)이 들어가도 된다.
- COUNT: count...By 반환타입 long
- EXISTS: exists...By 반환타입 boolean
- 삭제: delete...By, remove...By 반환타입 long
- DISTINCT: findDistinct, findMemberDistinctBy
- LIMIT: findFirst3, findFirst, findTop, findTop3
주의 사항
- 이 기능은 엔티티의 필드명이 변경되면 인터페이스에 정의한 메서드 이름도 꼭 함께 변경해야 한다. 그렇지 않으면 애플리케이션을 시작하는 시점에 오류가 발생한다.
- 이렇게 애플리케이션 로딩 시점에 오류를 인지할 수 있는 것이 스프링 데이터 JPA의 매우 큰 장점이다.
메소드 이름으로 JPA NamedQuery 호출
- JPA의 NamedQuery를 호출할 수 있다.
- 실무에서는 잘 쓰이지 않는다.
예)
@NamedQuery
@Entity
@NamedQuery(
name="Member.findByUsername",
query="select m from Member m where m.username = :username")
public class Member {
... }
JPA를 직접 사용해서 Named 쿼리 호출
public class MemberRepository {
public List<Member> findByUsername(String username) {
...
List<Member> resultList =
em.createNamedQuery("Member.findByUsername", Member.class)
.setParameter("username", username)
.getResultList();
} }
스프링 데이터 JPA로 NamedQuery 사용
@Query(name = "Member.findByUsername")
List<Member> findByUsername(@Param("username") String username);
@Query를 생략하고 메서드 이름만으로 Named 쿼리를 호출할 수 있다.
스프링 데이터 JPA로 NamedQuery 호출
public interface MemberRepository
extends JpaRepository<Member, Long> { //** 여기 선언한 Member 도메인 클래스
List<Member> findByUsername(@Param("username") String username);
}
- 스프링 데이터 JPA는 선언한 "도메인 클래스 + .(점) + 메서드 이름"으로 Named 쿼리를 찾아서 실행
- 만약 실행할 Named 쿼리가 없으면 메서드 이름으로 쿼리 생성 전략을 사용한다.
참고
- 스프링 데이터 JPA를 사용하면 실무에서 Named Query를 직접 등록해서 사용하는 일은 드물다.
- 대신 @Query 를 사용해서 리파지토리 메소드에 쿼리를 직접 정의한다.
@Query 어노테이션을 사용해서 Repository Interface에 쿼리 직접 정의
메서드에 JPQL 쿼리 작성
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 쿼리라 할 수 있음
- JPA Named 쿼리처럼 애플리케이션 실행 시점에 문법 오류를 발견할 수 있음(매우 큰 장점!)
'💻dev > 🌱Java+Spring' 카테고리의 다른 글
Spring Data JPA | 파라미터 바인딩과 반환 타입 (0) | 2023.05.09 |
---|---|
Spring Data JPA | @Query, 값, DTO 조회하기 (0) | 2023.05.09 |
JPA | JPQL 중급 문법 뿌시기 - 다형성 쿼리, 엔티티 직접 사용, Named 쿼리, 벌크 연산 (0) | 2023.05.04 |
JPA | JPQL 중급 문법 뿌시기 - 페치 조인(fetch join) (0) | 2023.05.04 |
JPA | JPQL 중급 문법 뿌시기 - 경로 표현식, 명시적 조인 vs 묵시적 조인 (0) | 2023.05.04 |