[Querydsl] 15. Case문과 상수, 문자 더하기

민정·2023년 1월 9일

QueryDSL

목록 보기
15/18
post-thumbnail

✨ Case 문

select, where, orderBy절에 사용 가능

특정 조건(값)일 때, 특정 값을 반환하도록 하고 싶을 때 Case문을 사용하면 된다.

✅ 간단한 조건

딱 특정한 값을 when의 파라미터로 적을 수 있을 때

select절 .when().then() .otherwise()

	/**
     * case문 - 단순 조건
     */
    @Test
    public void basicCase() throws Exception {
        List<String> result = queryFactory
                .select(member.age
                        .when(10).then("열살")
                        .when(20).then("스무살")
                        .otherwise("기타"))
                .from(member) // from절 안쓰면 No sources given 오류 발생
                .fetch();

        for (String s : result) {
            System.out.println("s = " + s);
        }
    }

✅ 복잡한 조건

CaseBuilder()사용

/**
     * case문 - 복잡한 조건 - CaseBuilder()사용
     */
    @Test
    public void complexCase() throws Exception {
        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) // from절 안쓰면 No sources given 오류 발생
                .fetch();

        for (String s : result) {
            System.out.println("s = " + s);
        }
    }

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

정렬 조건

  1. 0 ~ 30살 아닌 회원 가장 먼저 출력
  2. 0 ~ 20살 회원 출력
  3. 21 ~ 30살 회원 출력
/**
     * case문 - orderBy에서 case문 함께 사용
     */
    @Test
    public void orderByCase() throws Exception {
        // 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) // 나이에 따라서 rankPath는 1, 2, 3이 조회됨
                .from(member)
                .orderBy(rankPath.desc()) // rankPath로 정렬
                .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);
        }
    }

근데 쓸 일이 있을까?

강사님은 왠만하면 DB의 데이터 가공(열 살, 스무 살등)은 DB에서 처리하지 않음.

DB는 필터링, 그룹핑을 통해서 필요한 데이터를 걸러서 가져오는 역할만 하고, 나머지 처리(보여주는것)들은 애플리케이션(프레젠테이션 레이어)에서 처리


✨ 상수, 문자 더하기

✅ 상수

사용법

Expressions.constant("상수")

select 절에서 A라는 상수를 항상 같이 select하려면

    /**
     * 상수 - Expressions.constant("상수")
     */
    @Test
    public void constant() throws Exception {
        List<Tuple> result = queryFactory
                .select(member.username, Expressions.constant("A")) // 상수
                .from(member)
                .fetch();

        for (Tuple tuple : result) {
            System.out.println("tuple = " + tuple);
        }
    }

JPQL, SQL을 보면 상수는 select 절에 포함하지 않음.


✅ 문자 더하기 - 자주 사용!

select절에 concat(문자열) 사용!

🚨 주의

문자 아닌 타입들은 stringValue()로 문자로 변환 필요! (ENUM 처리시에도 자주 사용!)

/**
     * 문자 더하기
     */
    @Test
    public void concat() throws Exception {

        // username_age로 문자열 합쳐서 select하고 싶을 때
        List<String> result = queryFactory
                .select(member.username.concat("_").concat(member.age.stringValue())) // 문자 아닌 타입들은 stringValue()로 문자로 변환 가능(ENUM 처리시에도 자주 사용!)
                .from(member)
                .where(member.username.eq("member1"))
                .fetch();


        for (String s : result) {
            System.out.println("s = " + s);
        }
    }


SQL : age string으로 타입 바뀌어서 casting 됨!

💡 팁!

문자가 아닌 다른 타입들은 stringValue()로 문자로 변환 가능!
특히 ENUM문자열로 변환할때 자주 사용!



출처

김영한 강사님 - 인프런 실전! Querydsl

0개의 댓글