동적 쿼리를 해결하는 두번째 방법인 Where 다중 파라미터 사용에 대해 알아보겠습니다.

코드가 정말 깔끔해져서 실무에서 많이 사용합니다.

Where 다중 파라미터 사용

검색조건에 따라서 username이 member1 이거나 age가 10살인 사람을 찾고 싶다고 가정해봅시다.

import com.querydsl.core.types.dsl.BooleanExpression;

@BeforeEach
void setUp() {
    queryFactory = new JPAQueryFactory(em);

    Team teamA = new Team("teamA");
    Team teamB = new Team("teamB");
    em.persist(teamA);
    em.persist(teamB);

    Member member1 = new Member("member1", 10, teamA);
    Member member2 = new Member("member2", 20, teamA);
    Member member3 = new Member("member3", 30, teamB);
    Member member4 = new Member("member4", 40, teamB);
    em.persist(member1);
    em.persist(member2);
    em.persist(member3);
    em.persist(member4);
}

@DisplayName("WhereParam")
@Test
void dynamicQuery_WhereParam() {
    String usernameParam = "member1";
    Integer ageParam = null;

    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();
}

//...3
private Predicate usernameEq(String usernameCond) {
		//...1
    if (usernameCond == null) {
        return null;
    }
    return member.username.eq(usernameCond);
}

//...3
private BooleanExpression ageEq(Integer ageCond) {
    if (ageCond == null) {
        return null;
    }
    return member.age.eq(ageCond);
}
  1. where 조건에 null 값은 무시됩니다.

  2. 메서드들은 삼항연산자로 간단하게 리팩토링 할 수 있겠죠.

    private Predicate usernameEq(String usernameCond) {
        return usernameCond!= null ? member.username.eq(usernameCond) : null;
    }
    
    private Predicate ageEq(Integer ageCond) {
        return ageCond != null ? member.age.eq(ageCond) : null;
    }
    

    참고로 삼항연산자는 긍정을 먼저 사용하는게 낫죠.

  3. Predicate 보다는 BooleanExpression 을 사용하는게 낫습니다.

    메서드를 조합해서 사용하려면 BooleanExpression 를 사용해야하기 때문입니다. → 자세히

    어차피 BooleanExpression 는 Predicate 를 상속받고 있습니다.

실행해서 쿼리를 확인해봅시다.

Untitled

ageParam 에 null 을 넣었으니 조건이 빠졌습니다. 동적 쿼리가 작동했다는 것을 알 수 있습니다.

Where 다중 파라미터 사용의 장점

쿼리 자체의 가독성이 높아진다.

이렇게 메서드를 따로 만들면 귀찮다고 생각할 수 있는데요, 사실 개발할 때 메서드 명으로 동작을 유추하는 경우가 많습니다. usernameEq 은 username 과 같다는게 직관적으로 보여서 동적쿼리가 머리속에서 정리가 되죠.