JPA

[QueryDSL] Pageable 정렬하기

향각산 2024. 2. 14. 22:52

QueryDsl과 Pageable을 이용한 Sort 기능 사용법

QueryDsl에서는 Client가 제공해준 Order를 사용하는 방법이 여러가지가 있다.

그 중 다음과 같은 코드를 사용하면 복잡한 분석기능을 사용하지않고, 클라이언트가 pageable에 제공하는 sort 정보를 모두 한 코드로 사용할 수 있다.

for (Sort.Order order : pageable.getSort()) {
     PathBuilder<Object> path = new PathBuilder<Object>(Object.class, order.getProperty());
     query.where(builder).orderBy(new OrderSpecifier(com.querydsl.core.types.Order.valueOf(order.getDirection().name()), path));
}

JPAQueryFactory에 where에 pageable.getSort()를 분석해서 추가해주는 코드이다.

Entity에 종속적이지 않고 공통으로 적용할 수 있다.

(존재하지 않는 컬럼등은 처리할 수 없음)

단점은 매번 페이징이 필요한 코드에 직접 추가해줘야 한다. 

코드로 보면 이런 구조가 되기 쉽다.

 

        // where, offset, limit 처리 완료 후

        for (Sort.Order order : pageable.getSort()) {
            PathBuilder<Object> path = new PathBuilder<Object>(Object.class, order.getProperty());
            query.orderBy(new OrderSpecifier(com.querydsl.core.types.Order.valueOf(order.getDirection().name()), path));
        }

        var results = query.fetch();

        return new PageImpl<>(results, pageable, count == null ? 0 : count);

 

for 루프 안에서 동작하기 때문에 따로 분리해줘서 호출해야해서 기능자체는 편리하지만 사용할때 귀찮다.

 

Utils로 분리해서 관리하기

첫번째 방법을 좀 더 쉽게 사용하려면 Utils로 분리하면 된다.

하지만 Utils로 분리하는 경우 QClass에 종속성이 생기게 된다.

하지만, 여러곳에서 사용하기 훨씬 편하고, 위 코드처럼 복잡하게 쿼리를 나눌 필요가 없어진다.

public abstract class QuerydslUtils {

    public static <T> OrderSpecifier<?>[] getSort(Pageable pageable, EntityPathBase<T> qClass) {
        return pageable.getSort().stream().map(order ->
                        new OrderSpecifier(
                                Order.valueOf(order.getDirection().name()),
                                Expressions.path(Object.class, qClass, order.getProperty())
                        )).toList()
                .toArray(new OrderSpecifier[0]);
    }
}

 

                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .orderBy(QuerydslUtils.getSort(pageable, qProduct)).fetch();

        return new PageImpl<>(results, pageable, count == null ? 0 : count);

기존처럼 offset, limit까지 끝난 query를 들고 orderBy를 설정 후 다시 fetch()를 호출하지 않고, 쿼리 내에서 자연스럽게 해결할 수 있다.

다만 어떤 QClass를 기준으로 정렬할것인지 정보가 필요하다.

위 코드는 qProduct 데이터에서 Client가 넘겨준 sort를 기준으로 정렬된다.

'JPA' 카테고리의 다른 글

[JPA] MySQL smallint Java Integer에 매핑하기  (0) 2023.11.16
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함