쿼리 메서드 - 2

페이징과 정렬

  • 순수 JPA

public List<Member> findByPage(int age, int offset, int limit) {
   return em.createQuery("select m from Member m where m.age = :age order by m.username desc", Member.class)
            .setParameter("age", age)
            .setFirstResult(offset)
            .setMaxResults(limit)
            .getResultList();
}
public long totalCount(int age) {
    return em.createQuery("select count(m) from Member m where m.age = :age", Long.class)
            .setParameter("age", age)
            .getSingleResult();
}
  • 스프링 데이터 JPA

스프링 데이터 JPA는 쿼리 메서드에 페이징과 정렬 기능을 사용할 수 있도록 2가지 파라미터를 제공한다.

  • org.springframework.data.domain.Sort : 정렬 기능

  • org.springframework.data.domain.Pageable : 페이징 기능(내부에 Sort 포함)

반환 타입

  • org.springframework.data.domain.Page : 추가 count 쿼리 결과를 포함하는 페이징

  • org.springframework.data.domain.Slice : 추가 count 쿼리 없이 다음 페이지만 확인 가능(내부적으로 limit + 1조회)

  • List : 자바 컬렉션, 추가 count쿼리 없이 결과만 반환

사용 예제

JpaRepository

테스트 코드

  • 두 번째 파라미터로 받은 Pageable은 인터페이스다. 실제 사용할 때는 해당 인터페이스를 구현한 PageRequest객체를 사용한다.

  • PageRequest는 현재 페이지, 조회할 데이터 수를 파라미터로 받을 수 있고 추가로 정렬 정보(예: username을 DESC로)도 파라미터로 사용할 수 있다.

여기서 반환 타입을 Slice로 하면 count쿼리는 나가지 않고 내부적으로 limit으로 설정한 3보다 +1한 limit 4를 실행한다.

Page 인터페이스

Slice 인터페이스

이렇게 count쿼리를 불필요한 join을 하지 않게 분리할 수도 있다.(전체 count 쿼리는 매우 무겁다.)

페이지를 유지하면서 엔티티를 DTO로 변환할 수 있다.

벌크성 수정 쿼리

순수 JPA

영향받은 로우의 수를 반환한다.

스프링 데이터 JPA

@Modifying어노테이션으로 벌크성 수정, 삭제 쿼리를 날릴 수 있다. 벌크성 쿼리를 실행하고 나서 영속성 컨텍스트를 초기화 하려면 @Modifying(clearAutomatically = true)로 한다.(기본 값: false)

벌크 연산은 영속성 컨텍스를 무시하고 실행하기 때문에 영속성 컨텍스트에 있는 엔티티의 상태와 DB 엔티티 상태가 달라질 수 있다.

영속성 컨텍스트에 엔티티가 없는 상태에서 벌크 연산을 먼저 실행하거나, 벌크 연산 직후 영속성 컨텍스트를 초기화 해야 한다.

@EntityGraph

지연로딩(LAZY)인 관계를 페치 조인으로 조회할 수 있다.

공통 메서드를 오버라이드 한다.

JPQL + 엔티티 그래프를 사용할 수도 있다.

메서드 이름으로 쿼리 생성할 때도 사용할 수 있다. 같이 조회할 일이 많으면 유용하다.

@NamedEntityGraph라는 기능도 있다.

EntityGraph는 사실상 페치 조인의 간편 버전이다.

JPA Hint

SQL 힌트는 아니고 JPA 구현체에게 제공하는 힌트다.

JPA Lock

쿼리 시 락을 걸 수 있다.

Last updated