반응형
페이징 연동하기
Spring Data JPA에서 Page와 Pageable을 이용하고, QueryDSL을 이용하여 페이징을 사용해보자.
가장 효율적인 방법
- 이전까지의 페이징 방법중 하나는 fetchCount()와 fetchResult()를 이용하는 방법이였다.
- 하지만 이는 단순히 count 처리하는 용도이기 때문에 QueryDSL에서는 이를 지원하지 않기로 결정했다고 한다.
- 따라서 count와 result를 더 효율적으로 이용하는 방법을 사용하자.
List<MemberTeamDto> content = queryFactory
.select(
new QMemberTeamDto(
member.id.as("memberId"),
member.username,
member.age,
team.id.as("teamId"),
team.name.as("teamName")
)
)
.from(member)
.leftJoin(member.team, team)
.where(
usernameEq(condition.getUsername()),
teamNameEq(condition.getTeamName()),
ageGoe(condition.getAgeGoe()),
ageLoe(condition.getAgeLoe())
)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
JPAQuery<Member> countQuery = queryFactory
.select(member)
.from(member)
.leftJoin(member.team, team)
.where(
usernameEq(condition.getUsername()),
teamNameEq(condition.getTeamName()),
ageGoe(condition.getAgeGoe()),
ageLoe(condition.getAgeLoe())
);
return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchCount);
- 위 방법은
offset
과limit
을 이용해 페이징 처리를 하고, 필요 조건에 따라 전체count
를 조회하여 페이징 정보를 제공하는 코드이다. - 먼저 기존과 동일하게 contents를 가져오지만
fetchResults()
를 이용하지 않고fetch()
를 사용한다. - 이는 당장 필요한 페이징 처리된 contents만 받아온다.
- 중요한 점은
PageableExecutionUtils.getPage(content, pageable, countQuery::fetchCount)
이다.PageableExecutionUtils
는springframework
에서 제공하는 페이징처리를 돕는util
이다.PageableExecutionUtils.getPage(컨텐츠 내용, 해당 쿼리에서 이용한 pageable객체, 전체 데이터 개수가 필요한 경우 사용할 count JPAQuery)
를 이용하면pageable
과content
를 확인하여 상황에 따라count 쿼리
를 호출하여 결과 Page 객체를 제공한다.
- 이렇게 페이징이 가능한 이유는 다음과 같다.
- 현재 조회된 페이지의
contents
개수가pageable.getPageSize()
보다 작은 경우
->현재 페이지 이전 페이지 수
*페이지 최대 사이즈
+현재 페이지의 contents 개수
의 연산 결과가 곧 전체contents
의 개수이기 때문에 굳이count쿼리
를 조회하지 않아도 전체count
를 알 수 있다.
- 현재 조회된 페이지의
- 이러한 방법을 이용한 페이징은
count 쿼리
에 불필요한join
을 제거할 수 있어 성능을 최적화 할 수 있다. - 또한 코드 리펙토링시에 내용쿼리와 카운트쿼리를 구분지어 가독성이 좋아진다.
반응형
'Java & Kotlin > Spring Data' 카테고리의 다른 글
[JPA] Cascade persist와 연관관계 (0) | 2022.06.24 |
---|---|
[QueryDSL] oneToMany 관계에서 여러 개의 fetchJoin 사용하기 (0) | 2022.06.24 |
[QueryDSL] gradle querydsl 설정하기 (0) | 2022.05.15 |
[QueryDSL] Spring Data JPA와 QueryDSL 사용하기 (0) | 2022.05.15 |
[QueryDSL] 벌크연산과 SQL Funtion (0) | 2022.05.15 |
[QueryDSL] 동적쿼리 (0) | 2022.05.14 |