[Querydsl] 17. 동적 쿼리

민정·2023년 1월 10일

QueryDSL

목록 보기
17/18
post-thumbnail

✨ 동적 쿼리란?

입력값이나 특정 상황에 따라 쿼리문이 변경될 수 있는 쿼리



✨ 동적 쿼리 - BooleanBuilder 사용

🌟 BooleanBuilder를 사용해서 동적쿼리 날리는 Test

    /**
     * 동적 쿼리 - BooleanBuilder 사용
     */
    @Test
    public void 동적쿼리_BooleanBuilder() throws Exception {
        String usernameParam = "member1";
        Integer ageParam = null;

        List<Member> result = searchMember1(usernameParam, ageParam);
        assertThat(result.size()).isEqualTo(1);
    }

🌟 searchMember1 함수

BooleanBuilder 사용해서 쿼리 날리고 결과 받아오는 함수

BooleanBuilder로 동적 쿼리 만들기

1. BooleanBuilder 인스턴스 생성

BooleanBuilder builder = new BooleanBuilder();

2. builder.and(), builder.or()로 조건 연결

ex) builder.and(member.username.eq(usernameCond));

3. queryFactory의 where의 파라미터로 builder 인스턴스 넘기기

    /**
     * 파라미터의 null 여부에 따라서 쿼리가 동적으로 바뀌어야함.
     */
    private List<Member> searchMember1(String usernameCond, Integer ageCond) {

        BooleanBuilder builder = new BooleanBuilder();
        // BooleanBuilder builder = new BooleanBuilder(member.username.eq(usernameCond)); // 초기값 설정도 가능. username은 필수라서 null이 들어오지 않는 경우.

        if(usernameCond != null){// usernameCond가 null이 아니면
            builder.and(member.username.eq(usernameCond)); // builder에 and 조건 추가
        }

        if(ageCond != null){// ageCond가 null이 아니면
            builder.and(member.age.eq(ageCond));// builder에 and 조건 추가
        }

        return queryFactory
                .selectFrom(member)
                .where(builder) // where에 builder
                .fetch();
    }

✔ 결과

CASE 1) name, age를 모두 주었을 때

파라미터 바인딩 둘다 되고, where절에 두개의 조건 and로 연결

CASE 2) age = null이면

where절을 보면 username만 조건으로 들어감



✨ 동적 쿼리 - Where 다중 파라미터 사용

  • 강사님 추천
  • where 조건에 null 값은 무시됨
    • 아래에서 소개하는 usernameEq, ageEq 함수에서 들어온 값이 null이면 null을 반환
    • where절에 여러개의 파라미터가 사용될 경우, 각 조건들 and 조건으로 묶이고, null값이면 무시

장점

  • 만든 메서드를 다른 쿼리에서도 재사용이 가능
  • 쿼리 가독성이 높아짐

각 함수 소개

  • 동적쿼리_WhereParam() : searchMember2로 username, age를 넘겨서 동적 쿼리를 실행하도록 함
  • searchMember2 : queryFactory에서 where절 파라미터로 usernameEq, ageEq함수의 반환 값을 넘김
  • usernameEq : 이름을 파라미터로 받아서 null 이아니면 조건식을 반환
  • ageEq : 나이를 파라미터로 받아서 null 이아니면 조건식을 반환

🌟 동적쿼리_WhereParam 함수

    /**
     * 동적 쿼리 - Where 다중 파라미터 사용
     * 김영한 선생님이 실무에서 좋아하신다고 하심!
     * BooleanBuilder보다 깔끔
     */
    @Test
    public void 동적쿼리_WhereParam() throws Exception {
        String usernameParam = "member1";
        Integer ageParam = null;

        List<Member> result = searchMember2(usernameParam, ageParam);
        assertThat(result.size()).isEqualTo(1);
    }

🌟 searchMember2 함수

private List<Member> searchMember2(String usernameCond, Integer ageCond) {
        return queryFactory
                .selectFrom(member)
                .where(usernameEq(usernameCond), ageEq(ageCond))// where: 파라미터에 null이 들어오면 무시
                // .where(allEq(usernameCond, ageCond)) // 두개 다 조립해서 결과 받는 함수 사용도 가능
                .fetch();
    }

🌟 usernameEq, ageEq 함수

 private BooleanExpression usernameEq(String usernameCond) {
        return usernameCond != null ? member.username.eq(usernameCond) : null; // if-else 간단해서 삼항연산자 사용
    }

    private BooleanExpression ageEq(Integer ageCond) {
        return ageCond != null ? member.age.eq(ageCond) : null;
    
    }

✅ 조립 가능

위에서 정의했던 usernameEq, ageEq함수의 반환 값을 .and()로 묶은 조건식을 반환하는 allEq함수

    // 조립 가능, 재사용도 가능
    private BooleanExpression allEq(String usernameCond, Integer ageCond){
        return usernameEq(usernameCond).and(ageEq(ageCond));
    }


출처

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

0개의 댓글