취준/SPRING
[JPA] QueryDsl에서 Custom Sorting 하는 법
Kawaii_Jordy
2021. 7. 23. 11:29
우선 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());
}