@BeforeEach
void setUp() {
queryFactory = new JPAQueryFactory(em);
Team teamA = new Team("teamA");
Team teamB = new Team("teamB");
em.persist(teamA);
em.persist(teamB);
Member member1 = new Member("member1", 10, teamA);
Member member2 = new Member("member2", 20, teamA);
Member member3 = new Member("member3", 30, teamB);
Member member4 = new Member("member4", 40, teamB);
em.persist(member1);
em.persist(member2);
em.persist(member3);
em.persist(member4);
}
@Test
public void paging1() {
List<Member> result = queryFactory
.selectFrom(member)
.orderBy(member.username.desc())
.offset(1) //0부터 시작(zero index)
.limit(2) //최대 2건 조회
.fetch();
assertThat(result.size()).isEqualTo(2);
}
테스트 코드를 실행하면 아래처럼 쿼리가 나갑니다.
JPQL 에는 직접 페이징을 넣지 않았습니다. 그래서 JPQL 에는 limit offset 이 없습니다. → 참고
추가로 JPA 방언에 따라서 다른 페이징 쿼리가 나갑니다. 예시로 Oracle 이면 row num 쿼리가 나갈겁니다.
<aside> ❗ 쿼리에는 limit offset 이 아니라 offset fetch 쿼리가 나갔습니다. 아마 hibernate5 에서 hibernate6으로 업그레이드 되면서 내부 파서에 큰 변화가 있었기 때문으로 예상됩니다. fetch 절은 limit 와 비슷하게 동작하는데요, 자동으로 최적화해서 변경해준듯 합니다.
[참고]
@BeforeEach
void setUp() {
queryFactory = new JPAQueryFactory(em);
Team teamA = new Team("teamA");
Team teamB = new Team("teamB");
em.persist(teamA);
em.persist(teamB);
Member member1 = new Member("member1", 10, teamA);
Member member2 = new Member("member2", 20, teamA);
Member member3 = new Member("member3", 30, teamB);
Member member4 = new Member("member4", 40, teamB);
em.persist(member1);
em.persist(member2);
em.persist(member3);
em.persist(member4);
}
@Test
public void paging2() {
QueryResults<Member> queryResults = queryFactory
.selectFrom(member)
.orderBy(member.username.desc())
.offset(1)
.limit(2)
.fetchResults();
assertThat(queryResults.getTotal()).isEqualTo(4);
assertThat(queryResults.getLimit()).isEqualTo(2);
assertThat(queryResults.getOffset()).isEqualTo(1);
assertThat(queryResults.getResults().size()).isEqualTo(2);
}
fetchResults() Deprecated →참고
테스트 코드를 실행하면 아래처럼 2개의 쿼리가 나갑니다. → 참고