ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JPA] QueryDsl에서 Pageable 객체를 이용한 Sort 방법
    스프링프레임워크/jpa 2020. 9. 9. 12:45

     

    우선 Order, Path, fieldName을 전달하면 OrderSpecifier 객체를 리턴하는 Util 클래스를 작성해서 Sort시 마다 사용할 수 있도록 한다.

    • Path 파라미터는 compileQuerydsl 빌드를 통해서 생성된 Q타입 클래스의 객체이다.
    • Sort의 대상이 되는 Q타입 클래스 객체를 전달한다.
    import com.querydsl.core.types.Order;
    import com.querydsl.core.types.OrderSpecifier;
    import com.querydsl.core.types.Path;
    import com.querydsl.core.types.dsl.Expressions;
    
    public class QueryDslUtil {
    
        public static OrderSpecifier<?> getSortedColumn(Order order, Path<?> parent, String fieldName) {
            Path<Object> fieldPath = Expressions.path(Object.class, parent, fieldName);
            return new OrderSpecifier(order, fieldPath);
        }
    }

    사용 방법은 아래와 같이 Pageable 객체의 sort 필드를 체크해서 OrderSpecifier 리스트 객체를 생성한다.

    private List<OrderSpecifier> getAllOrderSpecifiers(Pageable pageable) {
    
        List<OrderSpecifier> ORDERS = new ArrayList<>();
    
        if (!isEmpty(pageable.getSort())) {
            for (Sort.Order order : pageable.getSort()) {
                Order direction = order.getDirection().isAscending() ? Order.ASC : Order.DESC;
                switch (order.getProperty()) {
                    case "id":
                        OrderSpecifier<?> orderId = QueryDslUtil.getSortedColumn(direction, QRoom.room, "id");
                        ORDERS.add(orderId);
                        break;
                    case "user":
                        OrderSpecifier<?> orderUser = QueryDslUtil.getSortedColumn(direction, QUser.user, "name");
                        ORDERS.add(orderUser);
                        break;
                    case "category":
                        OrderSpecifier<?> orderCategory = QueryDslUtil.getSortedColumn(direction, QRoom.room, "category");
                        ORDERS.add(orderCategory);
                        break;
                    default:
                        break;
                }
            }
        }
    
        return ORDERS;
    }

    생성 된 OrderSpecifier 객체를 querydsl 검색의 orderBy 함수의 argument로 넣어준다.

    public Page<RoomStatistic> search(CsRoomStatisticFilter filter, Pageable pageable) {
    
        List<OrderSpecifier> ORDERS = getAllOrderSpecifiers(pageable);
    
        JPAQueryFactory queryFactory = new JPAQueryFactory(em);
    
           QueryResults<CsRoomStatistic> results = queryFactory
                    .select(Projections.constructor(RoomStatistic.class,
                            room.id,
                            room.createdDate,
                            room.updatedDate,
                            user.name,
                            user.jobInfo.name,
                            room.category,
                            type.name
                    ))
                    .from(room)
                    .join(user).on(room.createdUserId.eq(user.id)).fetchJoin()
                    .join(type).on(room.typeId.eq(type.id)).fetchJoin()
                    .where(
                            room.createdDate.between(filter.getSearchStartDate(), filter.getSearchEndDate())
                    )
                    .orderBy(ORDERS.stream().toArray(OrderSpecifier[]::new))
                    .offset(pageable.getOffset())
                    .limit(pageable.getPageSize())
                    .fetchResults();
    
        return new PageImpl<>(results.getResults(), pageable, results.getTotal());
    }

     

    이상으로 QueryDsl에서 Pageable 객체를 이용한 Sort 방법에 대해서 알아보았습니다.

     

    댓글

Designed by Tistory.