본문 바로가기

Spring

Querydsl 페이징과 카운터쿼리 최적화

728x90

1.Page<T>로 반환

public Page<MemberTeamDto> Page(Pageable pageable) {
	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)
                        .offset(pageable.getOffset())
                        .limit(pageable.getPageSize())
                        .fetch();

        JPAQuery<Long> countQuery = queryFactory
                .select(member.count())
                .from(member)
                .leftJoin(member.team, team);

        return PageableExecutionUtils.getPage(content,pageable,countQuery::fetchOne);
}

content 쿼리와 count쿼리를 나눠서 작성 후 PageableExecutionUtils.getPage() 메소드에 넣어서 반환한다.

 

getPage() 메소드는 아래와 같은 상황일 때 count쿼리를 날리지 않고 최적화 한다.

  • 페이지의 시작이면서 content 사이즈가 page 사이즈보다 작을 때
  • 마지막페이지일때(Offset+컨텐츠 사이즈)

2.Slice<T>로 반환

public Slice<MemberTeamDto> Slice(Pageable pageable) {
        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)
                        .offset(pageable.getOffset())
                        .limit(pageable.getPageSize()+1)
                        .fetch();

        boolean hasNext = false;
        if(content.size()>pageable.getPageSize()){
            hasNext = true;
            content.remove(pageable.getPageSize());
        }
        return new SliceImpl<>(content,pageable,hasNext);
    }

Slice는 pageable.getPageSize()+1만큼 조회하여 content.size()와 pageable.getPageSize()의 크기를 비교하여 다음페이지에 데이터가 있는지 없는지를 판단하여 hasNext를 결정한다.

 

content,pageable,hasNext를 SliceImpl생성자의 파라미터에 넣어 반환하면 Slice로 반환 할 수 있다. 

728x90

'Spring' 카테고리의 다른 글

Actuator  (0) 2023.11.03
javaMailSender를 이용한 이메일 인증(Naver)  (0) 2023.05.09
Querydsl 동적 쿼리  (0) 2023.04.26
Querydsl 프로젝션 결과 반환  (0) 2023.04.26
Querydsl gradle 설정  (0) 2023.04.26