-
카테고리
-
세부 분야
백엔드
-
해결 여부
미해결
QueryDSL 5.0.0 기준으로 강의 내용을 정리했는데 올바르게 이해한 것일까요?
23.03.07 04:26 작성 23.03.07 15:37 수정 조회수 1.56k
11
searchPageSimple()
: 조회 쿼리와 카운트 쿼리를 한번에 실행
searchPageComplex()
: 조회 쿼리와 카운트 쿼리를 분리
QueryDSL 5.0.0부터는 fetchResults()
와 fetchCount()
를 deprecated 메서드로 공지함에 따라, 강의 내용처럼 searchPageSimple()
과 searchPageComplex()
를 구분해서 구현할 필요 없이 searchPageComplex()
의 방식으로만 구현하면 됨.
@Override
public Page<MemberTeamDto> searchWithPaging(MemberSearchCond cond, 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)
.where(
usernameEq(cond.getUsername()),
teamNameEq(cond.getTeamName()),
ageGoe(cond.getAgeGoe()),
ageLoe(cond.getAgeLoe())
)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
// count 쿼리 (조건에 부합하는 로우의 총 개수를 얻는 것이기 때문에 페이징 미적용)
Long total = queryFactory
.select(member.count()) // SQL 상으로는 count(member.id)와 동일
.from(member)
.leftJoin(member.team, team)
.where(
usernameEq(cond.getUsername()),
teamNameEq(cond.getTeamName()),
ageGoe(cond.getAgeGoe()),
ageLoe(cond.getAgeLoe())
)
.fetchOne();
return new PageImpl<>(content, pageable, total);
}
이 때, total
을 아래와 같이 구할 수도 있지만
long total = queryFactory
.selectFrom(member)
.leftJoin(member.team, team)
.where(
usernameEq(cond.getUsername()),
teamNameEq(cond.getTeamName()),
ageGoe(cond.getAgeGoe()),
ageLoe(cond.getAgeLoe())
)
.fetch() // 조건에 부합하는 전체 데이터를 조회 (List)
.size(); // List의 길이로 total을 구하기
count 함수는 SQL 차원에서 지원하기 때문에 굳이 이렇게 전체 데이터를 받아온 뒤에 애플리케이션 레벨에서 별도로 size()
를 호출해서 구할 필요 없고, 처음부터 카운트 쿼리를 호출하는 것이 나음.
이유는 전체 데이터를 불러오고 나서 size()
로 구하는 방식은 영속성 컨텍스트에 데이터를 전부 받아온 뒤에 개수를 따로 세는 것이기 때문에 불필요하게 메모리를 잡아먹기 때문.
total
을 구하는 방식에 대한 내용은 강의에 언급되지 않았기 때문에 제가 따로 검색해보고 내린 결론입니다. 제가 생각한 것이 맞는지 궁금합니다.
이외에도 잘못된 부분이 있다면 지적해주시면 감사하겠습니다.
답변을 작성해보세요.
답변 1