WindsomeProject - OrderSpecifier을 이용한 동적 정렬

박민수·2024년 1월 16일
0

WindsomeProject

목록 보기
31/32
post-thumbnail

개요

이 포스팅에서는 메인 화면에서 상품을 등록일, 낮은 가격, 높은 가격, 상품명 별로 정렬하는 기능을 QueryDSL에서 제공하는 OrderSpecifier 클래스를 활용하여 구현한 과정에 대해서 간략하게 정리하고자 한다.

쿼리

현재 메인 화면에서 상품을 출력하는 쿼리는 Querydsl을 사용하여 작성되었다. 동적 정렬을 구현하기 위해 여러 개의 API를 만들어 호출하는 것은 리소스를 낭비하고 복잡성을 증가시킬 수 있다. Querydsl에서는 OrderSpecifier을 사용하여 정렬 조건을 간단히 추가할 수 있다. OrderSpecifier를 리스트로 선언한 이유는 현재는 하나의 정렬 조건이지만, 추후에 여러 개의 정렬 조건이 추가될 수 있기 때문이다.

/* ItemRepositoryCustomImpl.java */

@Override
public Page<MainItemDto> getMainItemPage(ItemSearchDto itemSearchDto, Pageable pageable) {
    QItem item = QItem.item;
        QItemImg itemImg = QItemImg.itemImg;

        List<MainItemDto> content = queryFactory
                .select(
                        new QMainItemDto(
                                item.id,
                                item.itemNm,
                                item.category,
                                item.itemDetail,
                                itemImg.imgUrl,
                                item.price,
                                item.discount)
                )
                .from(itemImg)
                .join(itemImg.item, item)
                .where(itemImg.repImgYn.eq("Y"))
                .where(itemNmLike(itemSearchDto.getSearchQuery())
                        .or(itemCategoryLike(itemSearchDto.getCategory()))
                        .and(item.itemSellStatus.eq(ItemSellStatus.SELL)))
                .orderBy(createOrderSpecifier(itemSearchDto))
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();

        JPAQuery<Long> total = queryFactory
                .select(item.count())
                .from(itemImg)
                .join(itemImg.item, item)
                .where(itemImg.repImgYn.eq("Y"))
                .where(itemNmLike(itemSearchDto.getSearchQuery()));

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

// ProductSearchDTO 객체의 정렬 기준에 따라 OrderSpecifier 배열을 생성하는 메서드
private OrderSpecifier[] createOrderSpecifier(ProductSearchDTO productSearchDto) {
    // OrderSpecifier 객체들을 담을 리스트를 생성
    List<OrderSpecifier> orderSpecifiers = new ArrayList<>();

    // 정렬 기준이 없거나, "new"이거나, 빈 문자열일 경우
    if (Objects.isNull(productSearchDto.getSort()) || productSearchDto.getSort().equals("new") || productSearchDto.getSort().isEmpty()) {
        // product.id를 기준으로 내림차순 정렬 (최신 상품 우선)
        orderSpecifiers.add(new OrderSpecifier(Order.DESC, product.id));
    } 
    // 정렬 기준이 "best"인 경우
    else if (productSearchDto.getSort().equals("best")) {
        // product.averageRating을 기준으로 내림차순 정렬 (평점 높은 순)
        orderSpecifiers.add(new OrderSpecifier(Order.DESC, product.averageRating));
    } 
    // 정렬 기준이 "low"인 경우
    else if (productSearchDto.getSort().equals("low")) {
        // product.price를 기준으로 오름차순 정렬 (가격 낮은 순)
        orderSpecifiers.add(new OrderSpecifier(Order.ASC, product.price));
    } 
    // 정렬 기준이 "high"인 경우
    else if (productSearchDto.getSort().equals("high")) {
        // product.price를 기준으로 내림차순 정렬 (가격 높은 순)
        orderSpecifiers.add(new OrderSpecifier(Order.DESC, product.price));
    } 
    // 정렬 기준이 "name"인 경우
    else if (productSearchDto.getSort().equals("name")) {
        // product.name을 기준으로 오름차순 정렬 (이름 순)
        orderSpecifiers.add(new OrderSpecifier(Order.ASC, product.name));
    }

    // 리스트에 담긴 OrderSpecifier 객체들을 배열로 변환하여 반환
    return orderSpecifiers.toArray(new OrderSpecifier[orderSpecifiers.size()]);
}
profile
안녕하세요 백엔드 개발자입니다.

0개의 댓글

관련 채용 정보