ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • #QueryDSL -3 - 기본문법 - Case문 / 상수,문자 더하기
    QueryDSL 2021. 3. 30. 14:41

    Case 문

     

    select, 조건절(where), order by에서 사용 가능

     

    단순한 조건

    List<String> result = queryFactory
               .select(member.age
                   .when(10).then("열살")
                   .when(20).then("스무살")
                   .otherwise("기타"))
               .from(member)
               .fetch();

    복잡한 조건

    List<String> result = queryFactory
             .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();

     

    orderBy에서 Case 문 함께 사용하기 예제

    참고: 강의 이후 추가된 내용입니다.

     

    예를 들어서 다음과 같은 임의의 순서로 회원을 출력하고 싶다면?

    1. 0 ~ 30살이 아닌 회원을 가장 먼저 출력

    2. 0 ~ 20살 회원 출력

    3. 21 ~ 30살 회원 출력

    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 = queryFactory
         .select(member.username, member.age, rankPath)
         .from(member)
         .orderBy(rankPath.desc())
         .fetch();
         
    for (Tuple tuple : result) {
         String username = tuple.get(member.username);
         Integer age = tuple.get(member.age);
         Integer rank = tuple.get(rankPath);
         System.out.println("username = " + username + " age = " + age + " rank = "+ rank);
    }

    Querydsl은 자바 코드로 작성하기 때문에 rankPath 처럼 복잡한 조건을 변수로 선언해서 select 절, orderBy 절에서 함께 사용할 수 있다.

     

    결과
    username = member4 age = 40 rank = 3
    username = member1 age = 10 rank = 2
    username = member2 age = 20 rank = 2
    username = member3 age = 30 rank = 1

     

    실무 주의!!!

    위의 예제처럼 가금적으면 열살 ,스무살 이렇게 변환하는것은 DB에서 안하는게 좋다.

    DB는 row data를 필터링하고 그루핑 혹은 필요하다면 계산하는 역할을 한다.

    최소한의 필터링과 그룹핑으로 데이터를 줄이는 일을하고 , 실제 전화하고 바꾸는 일은 DB에서 하면안된다.

    Applicaiton또는 presentation layer에서 해결을 해야한다.

     

    상수, 문자 더하기

    상수가 필요하면 Expressions.constant(xxx) 사용

    Tuple result = queryFactory
       .select(member.username, Expressions.constant("A"))
       .from(member)
       .fetchFirst();

    참고: 위와 같이 최적화가 가능하면 SQL에 constant 값을 넘기지 않는다. 상수를 더하는 것 처럼 최적화가 어려우면 SQL에 constant 값을 넘긴다.

     

    문자 더하기 concat

    String result = queryFactory
         .select(member.username.concat("_").concat(member.age.stringValue()))
         .from(member)
         .where(member.username.eq("member1"))
         .fetchOne();

    결과: member1_10

     

    참고: member.age.stringValue() 부분이 중요한데, 문자가 아닌 다른 타입들은 stringValue() 로 문 자로 변환할 수 있다. 이 방법은 ENUM을 처리할 때도 자주 사용한다.

     

    댓글

Designed by Tistory.