JAVA/JPA

순수 JPA레포지토리의 페이징과 스프링 데이터 JPA레포지토리의 페이징.

gracelove91 2020. 2. 10. 22:44

순수 JPA레포지토리의 페이징과 스프링 데이터 JPA레포지토리의 페이징.

순수 JPA레포지토리

MemberJpaRepository.class

public List<Member> findByPage(int age, int offset, int limit) {
    return em.createQuery("select m from Member as m" +
                " where m.age = :age" +
                " order by m.username asc", Member.class)
            .setParameter("age", age)
            .setFirstResult(offset)
            .setMaxResults(limit)
            .getResultList();
}

MemberJpaRepositoryTest.class

@Transactional
@Test
void paging() {
    memberJpaRepository.save(new Member("member1", 10));
    memberJpaRepository.save(new Member("member2", 10));
    memberJpaRepository.save(new Member("member3", 10));
    memberJpaRepository.save(new Member("member4", 10));
    memberJpaRepository.save(new Member("member5", 10));
    memberJpaRepository.save(new Member("member6", 10));

    int age = 10;
    int offset = 0;
    int limit = 3;

    List<Member> members = memberJpaRepository.findByPage(age, offset, limit); //member1, member2, member3
    for (Member member : members) {
        System.out.println("member = " + member);
    }
    long totalCount = memberJpaRepository.totalCountByAge(age);

    assertEquals(3, members.size());
    assertEquals(6, totalCount);
}

스프링 데이터 JPA 레포지토리

MemberRepository.class

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

MemberRepositoryTest.class

  • Sorting과 Pageable로 페이징을 추상화했다.
@Transactional
@Test
void paging() {
    memberRepository.save(new Member("member1", 10));
    memberRepository.save(new Member("member2", 10));
    memberRepository.save(new Member("member3", 10));
    memberRepository.save(new Member("member4", 10));
    memberRepository.save(new Member("member5", 10));
    memberRepository.save(new Member("member6", 10));

    int age = 10;
    int offset = 0;
    int limit = 3;

    PageRequest pageRequest = PageRequest.of(offset, limit, Sort.by(Sort.Direction.ASC, "username"));

    Page<Member> members = memberRepository.findByAge(age, pageRequest); //member1, member2, member3
    Page<MemberDto> map = members.map(member -> new MemberDto(member.getId(), member.getUsername(), null));
    for (MemberDto memberDto : map) {
        System.out.println("memberDto = " + memberDto);
    }

    List<Member> content = members.getContent();
    long totalElements = members.getTotalElements();

    assertEquals(6, totalElements);
    assertEquals("member1", content.get(0).getUsername());
}

Count 같은 통계쿼리 쓸 때 주의할 점

  • Page<T>타입의 경우 count 쿼리 또한 날린다.

  • 연관관계 있다면 Left Outer Join 해서 count 쿼리 날리기 떄문에 무겁다 떄문에 countQuery를 커스텀해주자.

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