개요
- DB의 Case 문(when, then, otherwise)을 사용해보자.
- select, 조건절(where), order by에서 사용 가능하다.
Case 문
@Test
void basicCase() {
//given
//when
List<String> result = jpaQueryFactory
.select(member.age
.when(10).then("열살")
.when(20).then("스무살")
.otherwise("기타"))
.from(member)
.fetch();
//then
for (String age : result) {
System.out.println("age = " + age);
}
// Console Log
// age = 열살
// age = 스무살
// age = 기타
// age = 기타
}
/**
* 복잡한 조건
* CaseBuilder 사용
*/
@Test
void complexCase() {
//given
//when
List<String> result = jpaQueryFactory
.select(new CaseBuilder()
.when(member.age.between(0, 20)).then("0~20살")
.when(member.age.between(21, 30)).then("21~30살")
.otherwise("기타"))
.from(member)
.fetch();
//then
for (String age : result) {
System.out.println("age = " + age);
}
}
/**
* orderBy 에서 Case 문 함께 사용
* 다음과 같은 임의의 순서로 회원을 출력하고 싶다면?
* 0 ~ 30살이 아닌 회원을 가장 먼저 출력
* 0 ~ 20살 회원 출력
* 21 ~ 30살 회원 출력
*/
@Test
void orderByCase() {
//given
//when
NumberExpression<Integer> rankPath = new CaseBuilder()
.when(member.age.between(0, 20)).then(2)
.when(member.age.between(21, 30)).then(1)
.otherwise(3);
List<Tuple> result = jpaQueryFactory
.select(member.userName, member.age, rankPath)
.from(member)
.orderBy(rankPath.desc())
.fetch();
//then
for (Tuple tuple : result) {
String name = tuple.get(member.userName);
Integer age = tuple.get(member.age);
Integer rank = tuple.get(rankPath);
System.out.println("userName = " + name + " age = " + age + " rank = " + rank);
}
// Console Log
// userName = member4 age = 40 rank = 3
// userName = member1 age = 10 rank = 2
// userName = member2 age = 20 rank = 2
// userName = member3 age = 30 rank = 1
}
- Querydsl은 자바 코드로 작성하기 때문에 rankPath 처럼 복잡한 조건을 변수로 선언해서 select 절, orderBy 절에서 함께 사용할 수 있다.
- 해당 예제 같은 상황이라면 case 문 통해 필터링하여 DB에서 조회하는 것보다 데이터를 그대로 가져와서 서비스단에서 비지니스 로직을 구현하는 것이 더 좋다고 한다.