본문 바로가기
Back/JPA

[JPA, QueryDSL] 동적 정렬 OrderSpecifier

by 은z 2024. 7. 31.

 

상황

QueryDSL을 사용하여 목록을 조회하는 쿼리를 작성하던 중에 정렬 조건을 동적으로 처리해야 했다.

QueryDSL로 정렬하는 정적, 동적 방법을 알아보고 정리해보겠다.

 

 


실행환경 및 버전

  • QueryDSL: 5.0.0
  • JDK : open JDK 11
  • Spring Boot : 2.7.9

 

✔️정적 정렬 

 

// Sample.java의 Qclass가 생성되어 있다고 가정한다.

public List<Sample> findSampleList(String code) {
    return jpaQueryFactory.select(
                    Projections.constructor(Sample.class,
                            sample.no,
                            sample.title
                    )
            )
            .from(sample)
            .orderBy(sample.no.asc()) // 정적 정렬 방법
            .fetch();
}

📌 orderBy() 에 sample.no.asc() 를 사용하여 no 값이 정순으로 정렬되도록 구현했다.

 

✔️동적 정렬

이제 위에 코드에서 변형을 해보자.

만약 매개변수로 들어온 code 값에 따라 정렬 기준이 달라지면 어떻게 구현할까?

이럴 경우를 위해 QueryDSL 은 OrderSpecifier class 를 제공하고 있다.

 

OrderSpecifier 을 사용한 동적 정렬 방법을 코드를 통해 살펴보자.

// Sample.java의 Qclass가 생성되어 있다고 가정한다.

public List<Sample> findSampleList(String code) {
    return jpaQueryFactory.select(
                    Projections.constructor(Sample.class,
                            sample.no,
                            sample.title
                    )
            )
            .from(sample)
            .orderBy(createOrderSpecifier(code)) // 동적 정렬 방법
            .fetch();
}


private OrderSpecifier[] createOrderSpecifier(String code) {
    List<OrderSpecifier> orderSpecifiers = new ArrayList<>();

    if(code.equals("A")) {
        orderSpecifiers.add(new OrderSpecifier(Order.DESC, sample.no));
    }else if(code.equals("B")) {
        orderSpecifiers.add(new OrderSpecifier(Order.ASC, sample.createDt));
    }

    return orderSpecifiers.toArray(new OrderSpecifier[orderSpecifiers.size()]);
}

 

createOrderSpecifier 메소드를 처럼 OrderSpecifier 객체를 만들고, 필요한 조건에 따라 손쉽게 정렬 조건을 추가할 수 있다.

위 코드에서 OrderSpecifier을 List로 선언한 이유는 요구사항에 따라 여러 개의 정렬 조건이 추가될 수도 있기 때문이다.

 

댓글