쿼리 메소드 (1)

dongbin_Shin·2021년 7월 29일
3

스프링 데이터 JPA

목록 보기
2/6
post-thumbnail

  1. 메소드 이름으로 쿼리 생성
  2. NameQuery
  3. @Query - 리포지토리 메소드에 쿼리 정의
  4. 파라미터 바인딩
  5. 반환 타입
  6. 페이징과 정렬
  7. 벌크성 수정 쿼리
  8. @EntityGraph

쿼리 메소드 기능 3가지

  • 메소드 이름으로 쿼리 생성
  • 메소드 이름으로 JPA NamedQuery 호출
  • @Query 어노테이션을 사용해서 리파지토리 인터페이스에 쿼리 직접 정의

1. 메소드 이름으로 쿼리 생성

장점: 조건이 2개 이하인 쿼리일 때 매우 편리
단점: 조건이 많아지면 메소드의 이름이 지나치게 길어지는 단점

메소드 이름을 분석해서 JPQL 쿼리 실행

출처: 스프링 데이터 JPA 공식 문서

스프링 데이터 JPA가 제공하는 쿼리 메소드 기능

  • 조회: find...By,read...By,query...By,get...By
    • ...에 식별하기 위한 내용(설명)이 들어가도 된다. (기능에는 관여 X)
  • COUNT: count...By 반환 타입 long
  • EXISTS: exists...By 반환 타입 boolean
  • 삭제: deleted...By,remove...By 반환 타입 long
  • DISTINCT:findDistinct, findMemberDistinctBy
  • LIMIT: findFirst3,findFirst,findTop3,findTop3

참고: 이 기능은 엔티티의 필드명이 변경되면 인터페이스에 정의한 메서드 이름도 꼭 함께 변경해야 한다. 그렇지 않으면 어플 시작 시점에 오류가 발생한다.
이렇게 로딩 시점에 오류를 인지할 수 있는 것이 스프링 데이터 JPA의 매우 큰 장점이다.

2. NamedQuery

스프링 데이터 JPA를 사용하면 실무에서 Named Query를 직접 등록해서 사용할 일은 드물다.
대신 @query를 사용해서 리포지토리 메소드에 쿼리를 직접 정의한다.
(3. @Query, 리포지토리 메소드에 쿼리 정의하기 참고)

@NamedQuery 어노테이션으로 Named 쿼리 정의 (Member 엔티티)

@Entity
@NamedQuery( name="Member.findByUsername",
 query="select m from Member m where m.username = :username")
public class Member {
 ...
}

스프링 데이터 JPA로 NamedQuery 사용 (Member 리포지토리)

public interface MemberRepository
 extends JpaRepository<Member, Long> { //** 여기 선언한 Member 도메인 클래스
 
 // @Query(name = "Member.findByUsername") 생략 가능
 List<Member> findByUsername(@Param("username") String username);
} 
  • 스프링 데이터 JPA는 선언한 "도메인 클래스 + .(점) + 메서드 이름" 으로 Named 쿼리를 찾아서 실행 -> @Query(name = "Member.findByUsername") 생략 가능
  • 만약 실행할 Named 쿼리가 없으면 메서드 이름으로 쿼리 생성

3. @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);
}
  • @org.springframework.data.jpa.repository.Query 어노테이션 사용
  • 실행할 메서드에 정적 쿼리를 직접 작성 -> 이름 없는 Named 쿼리라 할 수 있음 (메서드 이름에 종속 X)
  • JPA Named 쿼리처럼 어플 실행 시점에 문법 오류 발견 가능 (매우 큰 장점)

참고: 실무에서는 메소드 이름으로 쿼리 생성 기능은 파라미터가 증가하면 메서드 이름이 매우 지저분해짐, 따라서 @Query 기능을 자주 사용

@Query, 값, DTO 조회

단순히 값 하나를 조회

@Query("select m.username from Member m")
List<String> findUsernameList();

JPA 값 타입(@Embedded)도 이 방식으로 조회 가능

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 명령어를 사용해야 함, 예제와 같이 DTO 생성자가 필요

MemberDto 클래스

package study.datajpa.repository;
import lombok.Data;
@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;
	}
}

"본 포스트는 작성자가 공부한 내용을 바탕으로 작성한 글입니다.
잘못된 내용이 있을 시 언제든 댓글로 피드백 부탁드리겠습니다.
항상 정확한 내용을 포스팅하도록 노력하겠습니다."

profile
멋있는 백엔드 개발자

0개의 댓글