[Querydsl] Pageable 객체로 정렬/페이징 하기

aqualung·2025년 2월 17일
post-thumbnail

프로젝트를 진행하던 중 동적 쿼리를 편하게 작성하기 위해 Querydsl을 도입했습니다.

기존 Spring DataPageable객체를 Querydsl에 도입해 보려 합니다.


queryFactory
	.selectFrom(recruitPost)
    .orderBy(recruitPost.createdDate.desc()) // 정적 정렬 조건
    .offset(pageable.getOffset())
    .limit(pageable.getPageSize())
    .fetch();

가장 간단하게 Pageable의 정보를 활용한다면 위와 같이 작성할 수 있습니다.

하지만 아직 orderBy()PageableSort정보는 사용하지 않고 있습니다.


OrderSpecifier

위와 같이 orderBy()는 하나 또는 배열(가변인자)인 OrderSpecifier 인자를 받고 있습니다.

Pageable을 받아 OrderSpecifier를 반환하는 메소드를 작성하면 될 것 같습니다.


Pageable -> OrderSpecifier

Pageable

PageableSortstream()으로 저장되어 있는 정렬 정보(Order)들을 가져올 수 있습니다.
Order에 담겨있는 정보로 OrderSpecifier를 생성해 주는 로직을 작성하면 될 것 같습니다.

pageable.getSort().stream().map(order -> {
	/*
    Sort.Order -> OrderSpecifier
    
    정렬 방향: getDirection(), isAscending(), isDescending()
    정렬에 사용할 속성: getProperty()
    */
})

PathBuilder

Querydsl에서 어떤 엔티티의 속성에 대한 경로를 동적으로 생성해 줄 필요가 있습니다.
엔티티는 Querydsl의 QClass를 사용하지만 어떤 속성을 사용할지에 대한 정보는 Pageable객체에 있기 때문입니다.

이를 테면 QMemberid를 기준으로 정렬할 때 QMemberQuerydslidPageable에 의존하고 있기 때문입니다. 저는 QMember.id에 대한 경로가 필요하기 때문에 경로를 생성해줄 메소드가 필요합니다.

다행히 Querydsl에서 PathBuilder라는 유연하게 경로 생성을 도와주는 객체가 있습니다.

public static <T> OrderSpecifier<?>[] getSort(Pageable pageable, EntityPathBase<T> qClass) {

        PathBuilder<T> pathBuilder = new PathBuilder<>(qClass.getType(), qClass.getMetadata());
}

QClassgetType()getMetadata()PathBuilder를 생성해 줍니다.

전체 코드

/* QuerydslUtils.java */
public abstract class QuerydslUtils {

    public static <T> OrderSpecifier<?>[] getSort(Pageable pageable, EntityPathBase<T> qClass) {

        PathBuilder<T> pathBuilder = new PathBuilder<>(qClass.getType(), qClass.getMetadata());

        return pageable.getSort().stream().map(order -> new OrderSpecifier<>(
                            order.isAscending() ? Order.ASC : Order.DESC,
                            pathBuilder.getString(order.getProperty())
        )).toArray(OrderSpecifier[]::new);
    }
}

PageableOrder를 사용해 QuerydslOrder를 생성자 매개변수로 넘겨 줍니다.

order.getProperty()로 정렬에 사용할 속성을 가져와 동적으로 경로를 생성해 매개변수로 넘겨 줍니다.

0개의 댓글