Kawaii_Jordy

[JPA] QueryDsl에서 Custom Sorting 하는 법 본문

취준/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());
}

https://uchupura.tistory.com/7

Comments