본문 바로가기

Spring

SpringData JPA를 활용한 페이징 및 정렬

728x90

1.반환 타입에 따른 count 쿼리

Page<Member> findByAge(@Param("age") int age,Pageable pageable); //count query 사용
Slice<Member> findByAge(@Param("age") int age, Pageable pageable); //count query 사용안함
List<Member> findByAge(@Param("age") int age, Pageable pageable); //count query 사용안함
List<Member> findByAge(@Param("age") int age, Sort sort); //count query 사용안함

2.Page와 Slice의 차이점

(1) Page

조회 쿼리 이후 전체 데이터 개수를 조회하는 카운트 쿼리가 실행된다.

총 데이터 개수가 필요할 때 사용하면 좋다.

(2) Slice

limit(size) +1 된 값을 조회 함으로 써 다음 Slice가 존재하는지 여부만 하기 때문에 데이터 양이 많을 경우 성능 상 유리하다.

총 데이터 개수가 필요하지 않고 다음 페이지 여부 확인에 사용된다.

 

3.Pageable

PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "username"));
Page<Member> page = memberRepository.findByAge(10, pageRequest);

Pageable은 인터페이스이므로 인터페이스를 구현한 PageRequest 객체를 사용한다.

PageRequest의 생성자 파라미터로 현재 페이지,조회할 데이터 수,정렬 정보를 파라미터로 사용할 수 있다.

4.Web 확장

(1) Controller

@GetMapping("/members")
    public Page<MemberDto> list(Pageable pageable){
        return memberRepository.findAll(pageable).map(MemberDto::new);
    }

파라미터로 Pageable를 받으면 api 요청시 page,size,sort를 요청 parameter로 받을 시 자동으로 PageRequest 객체가 생성된다.

(2) 요청 파라미터 예

URL:http://localhost:8080/members?page=0&size=3&sort=id,desc

5.Count Query 최적화

(1) Count Query 최적화 하지 않았을 경우

@Query(value = "select m from Member m left join m.team t where m.age =:age")
Page<Member> findByAge(@Param("age") int age,Pageable pageable);

 

최적화 하지 않았을 경우

멤버 중 파라미터로 받은 age와 같은 멤버들의 수를 구하는데 불필요한 Team의 join이 들어간다.

(2)Count Query 최적화

@Query(value = "select m from Member m left join m.team t where m.age =:age",
            countQuery ="select count (m.username) from Member m where m.age=:age" )
Page<Member> findByAge(@Param("age") int age,Pageable pageable);

최적화 시

Query를 선언 할때 CountQuery를 분리하여 불필요한 join이 들어가지 않도록 최적화 할 수 있다.

728x90