nu_s

[QueryDSL] 동적 쿼리 🦋 본문

QueryDSL

[QueryDSL] 동적 쿼리 🦋

woochii 2024. 2. 1. 19:01
728x90
반응형

동적 쿼리

  • 동적 쿼리를 해결하는 두가지 방법이 있다.
    1. BooleanBuilder
    2. Where 다중 파라미터

 

1. BooleanBuilder

@Test
public void dynamicQuery_BooleanBuilder() {
    String usernameParam = "member1";
    Integer ageParam = 10;

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

private List<Member> searchMember1(String usernameCond, Integer ageCond) {

    BooleanBuilder builder = new BooleanBuilder();

    if (usernameCond != null) {
        builder.and(member.username.eq(usernameCond));
    }

    if (ageCond != null) {
        builder.and(member.age.eq(ageCond));
    }

    return queryFactory
            .selectFrom(member)
            .where(builder)
            .fetch();
}
  • 테스트 코드를 보면 searchMember1 메서드에 파라미터를 넘겨준다.
  • 그럼 searchMember1 메서드를 살펴보자
  • 먼저 BooleanBuilder 객체를 생성한다. ➡️ BooleanBuilder는 간단히 말해서 where절의 조건을 생성해준다고 생각하면 된다.
  • 받아온 파라미터가 null인지 아닌지 검증을 한다. ➡️ null일 경우 조건문 안의 코드가 실행되지 않는다.
  • BooleanBuilder 객체를 where절에 넣어준다.

단점

  • 쿼리의 가독성이 좋지 않다.
  • 따라서 두 번째 방법을 추천한다.

2. Where 다중 파라미터 사용

@Test
public void dynamicQuery_WhereParam() {
    String usernameParam = "member1";
    Integer ageParam = 10;

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

private List<Member> searchMember2(String usernameCond, Integer ageCond) {
    return queryFactory
            .selectFrom(member)
            .where(usernameEq(usernameCond), ageEq(ageCond))
            .fetch();
}

private BooleanExpression usernameEq(String usernameCond) {
    return usernameCond == null ? null : member.username.eq(usernameCond);
}

private BooleanExpression ageEq(Integer ageCond) {
    return ageCond == null ? null : member.age.eq(ageCond);
}
  • 테스트 코드는 BooleanBuilder를 사용할 때와 똑같다.
  • 그러나 searchMember2 메서드는 쿼리만 남아 가독성이 좋아졌다.
  • null인지 아닌지 검증하는 usernameEq와 ageEq 메서드를 따로 생성해 where절의 파라미터로 넣어주었다.

장점

  • where 조건에 null 값이 들어와도 무시된다.
  • 메서드를 다른 쿼리에서도 재사용 할 수 있다.
  • 쿼리 자체의 가독성이 높아진다.
  • 조합이 가능하다.

 

조합하기

  • 원하는 조건들을 조합해서 사용할 수 있다.
  • 위의 코드를 예로 들자면
return queryFactory
            .selectFrom(member)
            .where(allEq(usernameCond, ageCond))
            .fetch();

private BooleanExpression allEq(String usernameCOnd, Integer ageCond) {
    return usernameEq(usernameCond).and(ageEq(ageCond));
}
  • 이름을 검색하는 조건과 나이를 검색하는 조건을 조합해 allEq()라는 메서드를 만들었다.
  • 단, 반환타입은 BooleanExpression이어야 한다.
  • 조합을 했다면 where절에 조합한 메서드를 넣어주기만 하면 된다.
  • null 체크는 항상 주의해서 처리해야 한다.

출처 : 인프런 실전! Querydsl

728x90
반응형

'QueryDSL' 카테고리의 다른 글

[QueryDSL] 순수 JPA & QueryDSL 🦋  (0) 2024.02.08
[QueryDSL] 벌크 연산 & SQL function 🦋  (0) 2024.02.03
[QueryDSL] 프로젝션과 결과 반환 🦋  (0) 2024.01.30
[QueryDSL] 기본 문법 🦋  (0) 2024.01.27
[QueryDSL] Q-TYPE 🦋  (0) 2024.01.23