SpringDataJPA 주요 메서드
save(S) : 새로운 엔티티는 저장하고 이미 있는 엔티티는 병합한다.
delete(T) : 엔티티 하나를 삭제한다. 내부에서 EntityManager.remove() 호출
findById(ID) : 엔티티 하나를 조회한다. 내부에서 EntityManager.find() 호출
getOne(ID) : 엔티티를 프록시로 조회한다. 내부에서 EntityManager.getReference() 호출
findAll(…) : 모든 엔티티를 조회한다. 정렬( Sort )이나 페이징( Pageable ) 조건을 파라미터로 제공할 수 있다.
참고: JpaRepository 는 대부분의 공통 메서드를 제공한다.
쿼리메소드 기능
쿼리 메소드 기능 3가지
- 메소드 이름으로 쿼리 생성(간단한 쿼리 사용 시)
- 메소드 이름으로 JPA NamedQuery 호출 (실무에서 거의 사용 안함)
- @Query 어노테이션을 사용해서 리파지토리 인터페이스에 쿼리 직접 정의(조금 복잡한 쿼리 사용 시)
*동적쿼리는 QueryDSL 사용(깔끔하고 유지보수성 좋음)
공식문서 참고
https://docs.spring.io/spring-data/jpa/reference/jpa/query-methods.html
JPA Query Methods :: Spring Data JPA
As of Spring Data JPA release 1.4, we support the usage of restricted SpEL template expressions in manually defined queries that are defined with @Query. Upon the query being run, these expressions are evaluated against a predefined set of variables. Sprin
docs.spring.io
스프링 데이터 JPA가 제공하는 쿼리 메소드 기능(메서드 이름으로 쿼리 생성)
짧은 쿼리들 작성 시 사용(복잡한 쿼리는 이렇게 사용할 수 없음. 2가지 조건 넘어가면 다른 방법 사용해야함)
조회: find…By ,read…By ,query…By get…By,
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.querymethods.query-creation
예:) findHelloBy 처럼 ...에 식별하기 위한 내용(설명)이 들어가도 된다.
COUNT: count…By 반환타입 long
EXISTS: exists…By 반환타입 boolean
삭제: delete…By, remove…By 반환타입 long
DISTINCT: findDistinct, findMemberDistinctBy
LIMIT: findFirst3, findFirst, findTop, findTop3
@Query 어노테이션을 사용해서 리파지토리 인터페이스에 쿼리 직접 정의
실무에서 많이 사용하는 기능
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);
@Query 로 단순한 값, DTO 조회하기
1. 값타입으로 조회하기
@Query("select m.username from Member m")
List<String> findUsernameList(); // username 타입이 String
2.DTO로 조회하기 (Dto 생성자와 매칭해야 한다)
예시에서는 team엔티티와 조인해서 조회하였음.
// Dto 조회시 new Operation 작성 필수(생성자와 매칭)
@Query("select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) from Member m join m.team t")
List<MemberDto> findMemberDto();
실제 실행 쿼리 :
select m1_0.member_id,m1_0.username,t1_0.name from member m1_0 join team t1_0 on t1_0.team_id=m1_0.team_id
* 컬렉션 파라미터 바인딩(IN절 사용)
실무에서 많이 사용
컬렉션과 IN절을 사용해서 조회하는 방법이다
// 컬렉션과 IN절 이용해서 조회
@Query("select m from Member m where m.username in :names")
List<Member> findByNames(@Param("names") Collection<String> names);
@Test // 컬렉션 IN절 사용한 쿼리
public void findByNames() throws Exception {
// given
Member m1 = new Member("AAA",10);
Member m2 = new Member("BBB",20);
memberRepository.save(m1);
memberRepository.save(m2);
List<Member> result = memberRepository.findByNames(Arrays.asList("AAA", "BBB"));
for (Member member : result) {
System.out.println("member = " + member);
}
}
반환타입의 유연성
반환타입의 유연성 : Spring Data JPA가 반환타입을 유연하게 지원해준다.
public interface MemberRepository extends JpaRepository<Member, Long> {
// Spring Data JPA가 반환타입을 유연하게 지원해줌.
List<Member> findListByUsername(String username); // 컬렉션
Member findMemberByUsername(String username); // 단건
Optional<Member> findOptionalByUsername(String username); // 단건 Optional
주의할 점
1.List로 반환하는 경우 DB에 일치하는 데이터가 없을때, List가 null이 아니라 비어있는 List를 반환한다.
@Test
public void returnType() throws Exception {
// given
Member m1 = new Member("AAA", 10);
Member m2 = new Member("BBB", 20);
memberRepository.save(m1);
memberRepository.save(m2);
List<Member> aaa = memberRepository.findListByUsername("dasfadf");
System.out.println("aaa = " + aaa.size());
}
출력값 : aaa = 0
2. 단 건으로 조회하는 경우 결과값이 없으면 null을 반환한다(JPA와 달리 Exception이 발생하지 않음)
Member findMember = memberRepository.findMemberByUsername("dasfadf");
System.out.println("findMember = " + findMember);
출력값 : findMember = null
DB조회 시 null인지 아닌지 모를때는 Optional을 활용하자
'Java > JPA' 카테고리의 다른 글
SpringDataJPA - 벌크성 수정 쿼리 (0) | 2024.01.10 |
---|---|
SpringDataJPA - 페이징을 쉽게 하는 법 (0) | 2024.01.10 |
JPA실전 2 - OSIV와 성능 (0) | 2023.12.12 |
JPA 실전2편 - 주문조회 API (0) | 2023.12.12 |
JPA 실전2편 - 회원 관련 API (0) | 2023.12.07 |