[Spring Data JPA] 쿼리 메서드 기능 ①
📌 스프링 데이터 JPA가 제공하는 쿼리 메서드 기능
- 메서드 이름으로 쿼리 생성
- 메서드 이름으로
JPA NamedQuery
호출@Query
어노테이션을 사용해서 리포지토리 인터페이스에 쿼리 직접 정의
[ 메서드 이름으로 쿼리 생성 ]
1. 순수 JPA
리포지토리
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();
}
테스트 실행 결과
2. 스프링 데이터 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
COUNT
:count...By
반환타입long
EXISTS
:exists…By
반환타입boolean
- 삭제:
delete…By
,remove…By
반환타입long
DISTINCT
:findDistinct
,findMemberDistinctBy
LIMIT
:findFirst3
,findFirst
,findTop
,findTop3
테스트 실행 결과
[ JPA NamedQuery
]
실무에서 거의 쓸 일 없으므로 알아만 두기!
1. 순수 JPA
이용
1) @NamedQuery
어노테이션으로 Named
쿼리 정의
@NamedQuery(
name="Member.findByUsername",
query="select m from Member m where m.username = :username"
)
public class Member { ... }
- 엔티티에
@NamedQuery
를 정의한다.
2) JPA
를 직접 사용해서 Named
쿼리 호출
public List<Member> findByUsername(String username) {
return em.createNamedQuery("Member.findByUsername", Member.class)
.setParameter("username", username)
.getResultList();
}
테스트 실행 결과
→ 실행은 잘 되지만 귀찮다😥 스프링 데이터 JPA
를 이용해보자!
2. 스프링 데이터 JPA
이용
1) 스프링 데이터 JPA
로 NamedQuery
사용
@Query(name = "Member.findByUsername")
List<Member> findByUsername(@Param("username") String username);
@Query
를 생략해도 된다!
→ 메서드 이름만으로NamedQuery
호출이 가능하다.
2) 스프링 데이터 JPA
로 Named
쿼리 호출
스프링 데이터 JPA는 선언한 <도메인 클래스
+ .
+ 메서드 이름
> 으로 Named
쿼리를 찾아서 실행한다.
만약 해당하는 쿼리가 없으면 메서드 이름으로 쿼리 생성 전략을 사용한다.
테스트 실행 결과
[ @Query
, 리포지토리 메서드에 쿼리 정의하기 ]
실무에서 많이 쓰이는 방법이다!
메서드에 JPQL
쿼리 작성
@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);
- 실행할 메서드에 정적 쿼리를 직접 작성하므로 이름 없는
Named
쿼리라고 할 수 있다. JPA Named
쿼리처럼 어플리케이션 실행 시점에 문법 오류를 발견할 수 있다!
참고: 동적쿼리는
Querydsl
를 써야 한다.
[ @Query
, 값, DTO
조회하기 ]
지금까지는 엔티티만 조회했는데,
이번에는 단순한 값이나DTO
를 조회하는 방법에 대해 알아보자!
1. 단순한 값 하나 조회
@Query("select m.username from Member m")
List<String> findUsernameList();
- JPA 값 타입(
@Embedded
)도 이 방식으로 조회할 수 있다.
테스트 실행 결과
2. DTO
로 직접 조회
@Query("select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) from Member m join m.team t")
List<MemberDto> findMemberDto();
DTO
로 직접 조회하려면- JPA의
new
명령어를 사용해야 한다. - 패키지 경로도 모두 적어줘야 한다.
- JPA의
- 그리고 생성자가 맞는
DTO
도 필요하다!
MemberDto.java
@Data
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;
}
}
테스트 실행 결과
[ 파라미터 바인딩 ]
파라미터 바인딩은
위치 기반
,이름 기반
두 가지가 있다.
1. 파라미터 바인딩
select m from Member m where m.username = ?0 //위치 기반
select m from Member m where m.username = :name //이름 기반
위치 기반은 가독성도 떨어지고, 유지보수하기도 어렵다. 그러므로 이름 기반을 사용하자!
@Query("select m from Member m where m.username = :name")
Member findMembers(@Param("name") String username);
2. 컬렉션 파라미터 바인딩
@Query("select m from Member m where m.username in :names")
List<Member> findByNames(@Param("names") Collection<String> names);
Collection
타입으로in
절 지원
Author And Source
이 문제에 관하여([Spring Data JPA] 쿼리 메서드 기능 ①), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@mmy789/Spring-Data-JPA-쿼리-메서드-기능1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)