스프링데이터 + JPA/스프링 데이터 JPA

15. 순수 JPA 페이징, 정렬

sdafdq 2023. 11. 21. 08:29

지금까지 뭐

select * from member;

이런 식으로 그냥 다 데려왔었는데,

우리가 DB에 있는 걸 사실 다 끌고 올 수는 없음.

적당한 단위로 끊어서 가지고 와야 함.

그래서 게시판 보면 페이지별로 끊어놓는 거임.

 

조건

나이가 10살

이름으로 내림차순

첫번째 페이지. 페이지당 보여줄 데이터는 3건

 

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();
}

일단은 그냥 10살이 아니고 이렇게 받게끔.

조회해 오는데 age가 같은거, 내림차순으로, 근데 페이징으로.

여기선 쿼리 안치고 저렇게 setFirstResult, setMaxResult로.

setFirstResult가 처음위치, 보통 offset이라고 하고,

setMaxResult가 그 offset을 시작으로 몇개나 뽑아올건지.

JPQL로 안하는 이유는 페이징이 DB마다 메커니즘도 그렇고 서로 다양하게 달라서 JPQL로 추상화 하는 것은 어렵다고..

그래서 아예 그냥 함수로 따로 처리하는 듯.

잘은 모르겠지만, JPQL로 페이징을 제공하려 하면 복잡해 질 수 있기 때문에.. 그런 듯.

https://www.inflearn.com/questions/1081124

 

여튼 저렇게 하고,

 

public long totalCount(int age){
    return em.createQuery("select count(m) from Member m where m.age = :age", Long.class)
            .setParameter("age", age)
            .getSingleResult();
}

이거는 총 데이터의 수.

하긴 뭐 게시판 인덱싱하는거? 페이지마다 10개씩 등. 이런 거 할 때는 알아야 할 듯..

count()로 하나니 그냥 singleResult

@Test
public 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));

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

    List<Member> result = memberJpaRepository.findByPage(age, offset, limit);
    long totalCount = memberJpaRepository.totalCount(age);

    assertThat(result.size()).isEqualTo(3);
    assertThat(totalCount).isEqualTo(5);
}

테스트.

10살 5개 넣고

 

가져와 봄.

페이징으로 3개 가져오는 거 확인했고,

아예 데이터의 총 개수는 5개 확인함.

테스트 제대로 잘 넘어갔음.

 

 

보통 저렇게 count 아는 쿼리랑, 데이터 가져오는 쿼리 이렇게 2개 날리나 봄.