잘가.. fetchResults, fetchCount

이윤준·2021년 12월 27일
5

Spring

목록 보기
2/3

Querydsl 5.0부터 fetchResults()fetchCount()가 deprecated되었다.

사유는 아래와 같다.

fetchResults() : Get the projection in QueryResults form. Make sure to use fetch() instead if you do not rely on the QueryResults.getOffset() or QueryResults.getLimit(), because it will be more performant. Also, count queries cannot be properly generated for all dialects. For example: in JPA count queries can’t be generated for queries that have multiple group by expressions or a having clause. Get the projection in QueryResults form. Use fetch() instead if you do not need the total count of rows in the query result.

fetchCount() : An implementation is allowed to fall back to fetch().size().

요약하자면, 모든 dialect에서 QueryResults로 count쿼리를 날리는 것이 완벽하게 지원되지 않기때문에, total count를 사용할 필요가 없다면, fetch()를 사용하라는 것이다.

total count가 필요하더라도, 안정성을 위해서는 fetch를 이용하고, count쿼리를 따로 날리는 방법이 좋을 것 같다.

기존에 코드를 이렇게 작성했다면

    @Override
    public Page<MemberTeamDto> searchPageSimple(MemberSearchCondition condition, Pageable pageable) {
       
       QueryResults<MemberTeamDto> results = queryFactory
                .select(new QMemberTeamDto(member.id, member.username, member.age, team.id, team.name))
                .from(member)
		.offset(pageable.getOffset())
        	.limit(pageable.getPageSize())
                .fetchResults();

        List<MemberTeamDto> content = results.getResults();
        long total = results.getTotal();

        return new PageImpl<>(content, pageable, total);

이런식으로 바꿀 수 있다.

    @Override
    public Page<MemberTeamDto> searchPageSimple(MemberSearchCondition condition, Pageable pageable) {
    
        List<MemberTeamDto> content = queryFactory
                .select(new QMemberTeamDto(member.id, member.username, member.age, team.id, team.name))
                .from(member)
		.offset(pageable.getOffset())
        	.limit(pageable.getPageSize())
                .fetch();

        return new PageImpl<>(content, pageable, content.size());

이것은 간단한 예시여서, 이렇게 작성하였지만, content.size()처럼 무조건 List의 size()함수를 이용하서 totalCount를 구하는 것은 바람직하지 않다.

int자료형이기 때문에, 데이터양이 많아진다면, 문제를 일으킬 수 도 있다.
DB에 count 쿼리를 따로 날리는 방법이 좋아보이긴 하나, DB 마다 count(*)의 작동방식이 다르기도 하니 각각의 상황에 맞춰서 해결법을 생각해야한다.

profile
욕심쟁이 개발자

0개의 댓글