주요 메서드

  • save(S) : 새로운 엔티티는 저장하고 이미 있는 엔티티는 병합한다.
  • delete(T) : 엔티티 하나를 삭제한다. 내부에서 EntityManager.remove() 호출
  • findById(ID) : 엔티티 하나를 조회한다. 내부에서 EntityManager.find() 호출
  • getOne(ID) : 엔티티를 프록시로 조회한다. 내부에서 EntityManager.getReference() 호출
  • findAll(…) : 모든 엔티티를 조회한다. 정렬( Sort )이나 페이징( Pageable ) 조건을 파라미터로 제공할 수 있다.

 

참고: JpaRepository는 대부분의 공통 메서드를 제공한다.

 

 

쿼리 메서드 기능

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

 

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

- 메소드 이름을 분석해서 JPQL 쿼리 실행해 준다.

 

순수 JPA와 Data JPA의 비교 분석.

 

  • 순수 JPA Repoistory
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();
}

 

  • 스프링 Data JPA
ublic interface MemberRepository extends JpaRepository<Member, Long> {
	List<Member> findByUsernameAndAgeGreaterThan(String username, int age);
}

문법 참조.

공식문서 : 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) interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") void del

docs.spring.io

 

 

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

 

참고: 이 기능은 엔티티의 필드명이 변경되면 인터페이스에 정의한 메서드 이름도 꼭 함께 변경해야 한다.

그렇지 않으면 애플리케이션을 시작하는 시점에 오류가 발생한다. (No Property 에러 뜸)

> 이렇게 애플리케이션 로딩 시점에 오류를 인지할 수 있는 것이 스프링 데이터 JPA의 매우 큰 장점이다.

 

 

2. 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 interface MemberRepository
extends JpaRepository<Member, Long> { //** 여기 선언한 Member 도메인 클래스
	List<Member> findByUsername(@Param("username") String username);
}

참고: 스프링 데이터 JPA를 사용하면 실무에서 Named Query를 직접 등록해서 사용하는 일은 드물다.

대신 @Query 를 사용해서 리파지토리 메소드에 쿼리를 직접 정의한다.

 

 

3. @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);
}

 

@org.springframework.data.jpa.repository.Query 어노테이션을 사용

실행할 메서드에 정적 쿼리를 직접 작성하므로 이름 없는 Named 쿼리라 할 수 있음

JPA Named 쿼리처럼 애플리케이션 실행 시점에 문법 오류를 발견할 수 있음(매우 큰 장점!)

 

> 참고: 실무에서는 메소드 이름으로 쿼리 생성 기능은 파라미터가 증가하면 메서드 이름이 매우 지저분해진다. 

따라서 @Query 기능을 자주 사용하게 된다.

 

 

** 동적쿼리는 queryDsl 사용하는게 제일 깔끔하다.

+ Recent posts