N + 1 문제
해결 방법
QueryDSL 사용이유
Projects 사용 이유
: QueryDSL에서 쿼리 결과를 DTO로 매핑하는 데 유용합니다. 특히, Projections.constructor()는 DTO의 생성자에 맞춰 쿼리 결과를 매핑할 수 있도록 합니다. 이 방법을 사용하면 Tuple 대신 원하는 DTO 객체를 직접 반환받을 수 있습니다.
public Page<GetBookSimpleResponse> findAllBooksByCategoryName(Pageable pageable, String categoryName) {
List<GetBookSimpleResponse> result = queryFactory
.select(Projections.constructor(
GetBookSimpleResponse.class,
book.bookId,
book.author.authorName,
book.bookTitle,
book.bookPrice,
book.bookSalePrice,
book.bookSalePercent,
image.imageUrl))
.from(book)
.join(bookCategory).on(bookCategory.book.eq(book))
.join(bookCategory.category, category)
.leftJoin(bookImage).on(bookImage.book.eq(book))
.where(category.categoryName.eq(categoryName))
.offset(pageable.getOffset()) // 페이지 시작점
.limit(pageable.getPageSize()) // 페이지 크기
.fetch();
Long total = Optional.ofNullable(queryFactory
.select(book.count())
.from(book)
.join(bookCategory).on(bookCategory.book.eq(book))
.join(bookCategory.category, category)
.where(category.categoryName.eq(categoryName))
.fetchOne()).orElse(0L);
return new PageImpl<>(result, pageable, total);
}
페이징 처리시 total을 따로 구하는 이유