DevKim

[Data JPA] 페이징과 정렬 본문

JPA

[Data JPA] 페이징과 정렬

on_doing 2021. 7. 1. 16:49
728x90

[ 페이징과 정렬 ]

반환 타입에 따라 Total count 쿼리를 날릴지 안 날릴지가 결정이 된다.


<1> 반환 타입이 Page 일 때

* Count 쿼리 사용 *

 

 pageRequest에 원하는 정보 넣고 만들어서 넘겨준 뒤, interface에서 Pageable로 받으면 끝이다.

PageRequest.of ( 찾을 페이지, 한 페이지의 사이즈, Sort 조건 )

   -> Sort 조건은 생략가능

page안에 많은 메서드가 제공된다.

 

[Interface]

Page<Member> findByAge(int age, Pageable pageable);

[Test]

@Test
    public void page() throws Exception{
        //given
        memberRepository.save(new Member("mwmber1",10));
        memberRepository.save(new Member("mwmber2",10));
        memberRepository.save(new Member("mwmber3",10));
        memberRepository.save(new Member("mwmber4",10));
        memberRepository.save(new Member("mwmber5",10));

        int age=10;
        PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "username"));

        //when
        Page<Member> page =memberRepository.findByAge(age,pageRequest);

        //then
        //조회된 데이터
        List<Member> content = page.getContent();

        //조회된 데이터 수
        assertThat(content.size()) .isEqualTo(3);

        //전체 데이터 수
        assertThat(page.getTotalElements()).isEqualTo(5);

        //페이지 번호
        assertThat(page.getNumber()).isEqualTo(0);

        //전체 페이지 번호
        assertThat(page.getTotalPages()).isEqualTo(2);

        //첫번 째 항목인가?
        assertThat(page.isFirst()).isTrue();

        //다음 페이지가 있는가?
        assertThat(page.hasNext()).isTrue();
    }

<2> 반환 타입이 Slice 일 때

* Count 쿼리 사용안함 *

 

 다음 페이지 있어 없어? 같이 다음이 있는지 단순히 확인만 하는 것

pageRequest에서 0번째에서 3개를 요청했는데,  Slice는 1개 더해서 limit 4개를 요청한다. 

다음 페이지 있는지 확인해서 다음 페이지 있으면 더보기 만들거나 할 때 사용한다고한다.

 

[Interface]

Slice<Member> findSliceByAge(int age, Pageable pageable);

[Test]

Total Count 쿼리를 날리지 않기 때문에, 전체 데이터 수나 전체 페이지 수를 반환하는 메서드는 제공하지 않는다.

@Test
public void slice() throws Exception{
      //given
      memberRepository.save(new Member("mwmber1",10));
      memberRepository.save(new Member("mwmber2",10));
      memberRepository.save(new Member("mwmber3",10));
      memberRepository.save(new Member("mwmber4",10));
      memberRepository.save(new Member("mwmber5",10));

      int age=10;
      PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "username"));

      //when
      Slice<Member> page =memberRepository.findSliceByAge(age,pageRequest);

      //then
      //조회된 데이터
      List<Member> content = page.getContent();

      //조회된 데이터 수
      assertThat(content.size()) .isEqualTo(3);

      //전체 데이터 수
      //        assertThat(page.getTotalElements()).isEqualTo(5);

      //페이지 번호
      assertThat(page.getNumber()).isEqualTo(0);

      //전체 페이지 번호
      //        assertThat(page.getTotalPages()).isEqualTo(2);

      //첫번 째 항목인가?
      assertThat(page.isFirst()).isTrue();

      //다음 페이지가 있는가?
      assertThat(page.hasNext()).isTrue();

}

<3> 반환타입을 List로 두는 경우 

* Count 쿼리 사용안함 & 메서드 제공 안함 *

->페이징 쿼리는 그냥 딱 0페이지부터 3개만 가져오고 싶고, 다음이 있는지 없는지 이런거 상관없을 때

List<Member> findListByAge(int age, Pageable pageable);

 


** 페이지를 유지하면서 엔티티를 DTO로 변환하기 **

 

간단한 실습이니까 Member로 바로 넘겼지만,

실무에선 절대절대 Member 그대로 넘기면 안되고, DTO로 변환해서 넘겨주어야한다.

 

map을 이용해서 DTO로 변환할 수 있다.

...

int age = 10;
PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "username"));

//when
Page<Member> page = memberRepository.findByAge(age, pageRequest);

/*
페이지를 유지하면서 엔티티를 DTO로 반환하기
*/
Page<MemberDto> memberDtos = page.map(m -> new MemberDto(member.getId(), member.getUsername(), member.getTeam()));

...

 

728x90
Comments