본문 바로가기
JPA

쿼리 메소드 기능

by Heesu.lee 2021. 1. 26.

쿼리 메소드 기능 3가지

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

메소드 이름으로 쿼리 생성

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

 

예) 이름과 나이를 기준으로 회원 조회 로직 작성

// 순수 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();
}


// 스프링 데이터 JPA
List<Member> findByUsernameAndAgeGreaterThan(String username, int age);

 

쿼리 메소드 필터 조건

JPA 공식 문저 참고 -

https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation 

 

Spring Data JPA - Reference Documentation

Example 109. Using @Transactional at query methods @Transactional(readOnly = true) public interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") v

docs.spring.io

참고로, 해당 기능은 파라미터 추가될 때마다 메소드 명이 계속 길어진다.
추가로, 엔티티의 필드명이 변경되면 인터페이스에 정의한 메서드 이름도 꼭 함께 변경해야 한다.
이는 실행 시점에 바뀐 부분이나 문제점을 파악할 수 있다.

 

JPA NamedQuery

JPA 의 NamedQuery 를 호출할 수 있다.

정적 쿼리이기 때문에 로딩 시점에 파싱하여 오류를 확인할 수 있다는 장점이 있다.

// @NamedQuery 어노테이션으로 Named 쿼리 정의
@Entity
@NamedQuery(  
	name="Member.findByUsername",
	query="select m from Member m where m.username = :username") 
public class Member {
	...
}


// JPA 를 직접 Named 쿼리 호출
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는 선언한 "도메인 클래스 + .() + 메서드 이름"으로 Named 쿼리를 찾아서 실행
만약 실행할
Named 쿼리가 없으면 메서드 이름으로 쿼리 생성 전략을 사용한다.
필요하면 전략을 변경할 수 있지만 권장하지 않는다.

 

@Query 레포지토리 메소드에 쿼리 정의하기

  • @org.springframework.data.jpa.repository.Query 어노테이션을 사용
  • 실행할 메서드에 정적 쿼리를 직접 작성하므로 이름 없는 Named 쿼리라 할 수 있음
  • JPA Named 쿼리처럼 애플리케이션 실행 시점에 문법 오류를 발견할 수 있음

@Query 를 사용한 JPQL 작성

복잡한 정적 쿼리에 대해선 @Query 기능을 통하여 문제 해결할 수 있지만,
동적 쿼리에 대해선 QueryDSL 을 참고하는게 좋다.

@Query 를 이용한 값 조회

값 타입 (임베디드, 프리미티브 타입)

값 타입 조회 예시

@Query 를 이용한 DTO 로 직접 조회

DTO 로 직접 조회 하려면 JPA 의 new 명령어 사용해야 한다. 그리고 그에 맞는 DTO 생성자가 필요

DTO 직접 조회 예시

 

참조

  • 해당 게시글은 김영한님의 실전 스프링 데이터 JPA 를 참고하여 작성하였습니다.

'JPA' 카테고리의 다른 글

Querydsl 기본 문법  (0) 2021.04.26
Querydsl 사용 개요  (0) 2021.04.25
객체지향 쿼리 언어  (0) 2021.01.25
프록시와 연관관계 관리  (0) 2021.01.20
값 타입  (0) 2021.01.19

댓글