⚙️백엔드 : Backend/DataBase
[QueryDSL] CaseBuilder 활용 조건식 표현
예옹이
2025. 6. 16. 19:04
SQL
에서 조건별로 값을 다르게 리턴하는 CASE
문은 자주 사용됩니다.
예를 들어, 아래와 같은 쿼리를 생각해볼 수 있습니다.
SELECT name,
score,
CASE
WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN 'B'
ELSE 'C'
END AS grade
FROM student;
이 코드를 Java
에서 QueryDSL
을 사용해 표현하려면 어떻게 작성해야 할까요?
QueryDSL에서 CASE문 작성 시 주의점
아래와 같은 코드를 작성했다고 가정해 봅시다.
student.score.goe(90).then(1)
.when(student.score.goe(80)).then(2)
.otherwise(3); // ❌ 컴파일 에러
이 경우 컴파일 에러가 발생했을겁니다.
왜냐면 queryDSL
에서는 단순히 .when()
과 .then()
을 이어 붙이는 방식이CaseBuilder
없이는 불가능하기 때문입니다.
특히나 범위 조건(>=
, =<
)같은 복잡한 조건들은 기본 문법만으로 처리하기가 더 어렵습니다.
그래서 CaseBuilder 사용
QueryDSL
은 복잡한 조건식, 특히 여러 when
조건을 처리하기 위해 CaseBuilder
클래스를 제공하고 있습니다.
예를 들어 위에 예시로 작성해둔 SQL
은 QueryDSL
에서
new CaseBuilder()
.when(student.score.goe(90)).then("A")
.when(student.score.goe(80)).then("B")
.otherwise("C");
이렇게 작성이 가능합니다.
CaseBuilder를 활용한 정렬 조건 작성 예시
저는 프로젝트에서 이중으로 orderBy
조건을 정리할 일이 있었습니다.
예를 들어서 답변 생성일(reply.createdAt
)을 기준으로 정렬할 때,
1. 답변 생성일이 없는 것(null)을 먼저 나오게 하기
2. 답변 생성일이 있다면 최근인 순서대로 정렬하기
위 조건처럼 데이터를 불러오고 싶었습니다.
그런데 아래처럼 기본적인 orderBy
로만 작성했더니 오류가 발생했습니다.
.orderBy(
reply.createdAt.isNull().desc(),
reply.createdAt.desc().nullsLast()
)
CaseBuilder를 활용한 문제 해결
.orderBy(
new CaseBuilder()
.when(reply.createdAt.isNull()).then(0)
.otherwise(1).asc(),
reply.createdAt.desc().nullsLast()
)
위 코드는 다음과 같은 의미를 갖습니다.
- reply.createdAt이 null이면 0 반환, 아니면 1 반환
- 이 기준으로 오름차순 정렬 = null 항목부터 표시
- 그 다음 실제 reply.createdAt 날짜 기준으로 내림차순
마무리
SQL
CASE WHEN
문을 QueryDSL
에서 구현할 때는 CaseBuilder
를 사용하자
단순 값 비교가 아닌 범위 혹은 복합 조건 비교는 CaseBuilder
로 처리하자