페이징: setFirstResult, setMaxResult 를 사용하여 페이징
정렬: JPQL 에 order by 절을 사용하여 정렬
페이징과 정렬 파라미터
org.springframwork.data.domain.Pagable: 페이징 기능 (내부에 Sort 포함)
org.springframwork.data.domain.Sort: 정렬기능
특별한 반환 타입
org.springframwork.data.domain.Page
추가 count 쿼리 결과를 포함하는 페이징
현재 페이지, 총 페이지, 총 개수, 쿼리 결과 등 다양한 정보를 갖고 반환
추가 count 쿼리를 조인 방식 등에 의해 별도로 지정해줄 필요가 있는 경우 @Query 에 countQuery 속성 값으로 JPQL 을 넣어주면 count 쿼리 대신 실행
map 메서드를 활용하여 쿼리 결과 엔티티만 DTO로 변환하여 Page 객체를 컨트롤러 단에서 반환할 수 있음
org.springframwork.data.domain.Slice
추가 count 쿼리 없이 다음 페이지만 확인 가능(내부적으로 limit + 1 조회)
count 쿼리가 나가지 않으므로 총 페이지, 개수 등을 확인할 수 없음
현재 페이지, 쿼리 결과 등을 반환
List
추가 count 쿼리 없이 결과 반환
추가적인 정보 없이 쿼리 결과만 반환함
변경 감지를 통해 테이블 열 하나하나 수정하는 것은 한 번에 여러 열을 수정하는 것에 비해 성능이 떨어진다. 따라서 여러 열을 한 번에 수정할 수 있는 기능인 벌크 연산을 지원한다.
순수 JPA 벌크 연산
em.createQuery 를 사용하여 직접 update 문을 작성한다.
이후 executeUpdate 를 실행하여 JPQL 을 실행하고, 수정이 일어난 열의 수를 반환받는다.
스프링 데이터 JPA 에서 벌크 연산
update 문을 @Query 어노테이션을 활용하여 인터페이스에 작성한다.
@Modifying 어노테이션을 추가로 사용하여 해당 쿼리가 executeUpdate 를 사용하여 실행해야하는 벌크 연산임을 명시하면, 데이터 JPA 가 벌크 연산으로 처리한다.
벌크 연산 주의
벌크 연산 실행 시 영속성 컨텍스트의 상태를 무시하고 직접 쿼리를 날리므로, DB와 영속성 컨텍스트의 데이터가 다른 문제가 발생한다.
따라서, 벌크 연산 실행 시 영속성 컨텍스트를 초기화해주어야 한다. (em.flush, em.clear)
데이터 JPA에서는 @Modifying 어노테이션에 clearAutomatically 속성 값을 true 로 설정해주면, 알아서 영속성 컨텍스트를 초기화한다.
데이터 JPA 에서는 쿼리를 메서드 이름, 반환 타입 등으로 구현을 자동화하는데, 페치 조인이 필요할 경우 어떻게 처리해야할까? (@Query 어노테이션에 join fetch 를 넣어 사용해도 됨)
데이터 JPA 에서 페치조인 사용하기
페치 조인이 필요한 메서드에 @EntityGraph 어노테이션을 추가한다.
@EntityGraph 의 attributePaths 속성 값으로 페치 조인해 올 필드를 설정하면 구현체에서 페치 조인을 사용하여 데이터를 가져오게 된다.
@Query 어노테이션을 사용하여 페치 조인 없이 쿼리를 작성한 후, @EntityGraph 어노테이션을 추가로 사용하여 페치 조인 관계만 추가할 수도 있다.
참고.
엔티티 그래프 기능은 JPA 2.2 부터 지원되는 기능이다.
@NamedEntityGraph 어노테이션을 사용하여 정적으로 엔티티 그래프를 만들어 놓고 가져다 사용할 수 있다.
em.createEntityGraph 메서드를 사용하여 동적으로 엔티티 그래프를 만들어 사용할 수도 있다.
엔티티 그래프를 jpa hint 에 넣으면 jpa 가 쿼리 실행 시 참고하여 동작한다.
JPA Hint
JPA 에서 쿼리를 실행할 때 순수 JPA 에서는 지원하지 않지만, 하이버네이트에서 지원하는 기능을 사용하고 싶을 때 JPA Hint 기능을 사용할 수 있다.
@QueryHints 어노테이션에 name, value 값으로 힌트를 문자열로 넣어 사용할 수 있다.
ex) readOnly
JPA Lock
DB 락 관리를 JPA에서 쉽게 할 수 있도록 하는 기능
데이터 JPA 에서는 @Lock 어노테이션을 메서드에 붙여 lock 기능을 쉽게 사용할 수 있다.