Querydsl - 동적 쿼리
인프런 실전! Querydsl 강의 내용 정리
Querydsl에서 동적 쿼리를 다루는 방식은 크게 2가지가 있다.
BooleanBuilder 사용
1
2
3
4
5
6
7
8
9
@Test
public void dynamicQuery_BooleanBuilder() throws Exception {
String usernameParam = "member1";
Integer ageParam = 10;
List<Member> result = searchMember1(usernameParam, ageParam);
assertThat(result.size()).isEqualTo(1);
}
다음과 같은 테스트 코드를 작성했다.
searchMember1() 메서드는 이름과 나이를 받아 리스트를 반환해주는 메서드이다.
이제 searchMember1를 BooleanBuilder 사용하여 만들어 보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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();
}
자 여기서 사용하는 것이 com.querydsl.core.BooleanBuilder 이다.
먼저 BooleanBuilder를 하나 만들어 준다음에
1
2
3
if (usernameCond != null) {
builder.and(member.username.eq(usernameCond));
}
다음과 같이 null 체크 후 아니라면 builder.and(member.username.eq(usernameCond)); 이렇게 넣어준거다.
물론 builder.or(member.username.eq(usernameCond)); 이런 것도 가능하다.
1
2
3
4
return queryFactory
.selectFrom(member)
.where(builder)
.fetch();
그 다음엔 .where(builder) where 절에 넣어주기만 하면 된다.

다음과 같이 이름만 넣고 나이는 null을 넣어줬더니
쿼리가 username만 들어가는 걸 볼 수 있다!
Where 다중 파라미터 사용
자 위와 같은 테스트 코드를 작성한다.
1
2
3
4
5
6
7
8
9
@Test
public void dynamicQuery_WhereParam() throws Exception {
String usernameParam = "member1";
Integer ageParam = 10;
List<Member> result = searchMember2(usernameParam, ageParam);
assertThat(result.size()).isEqualTo(1);
}
searchMember2() 메서드도 searchMember1과 같은 역할을 할 것이다.
1
2
3
4
5
6
private List<Member> searchMember2(String usernameCond, Integer ageCond) {
return queryFactory
.selectFrom(member)
.where(usernameEq(usernameCond), ageEq(ageCond))
.fetch();
}
Where 다중 파라미터 사용은 where 절에 메서드를 넣어 버린 거다 usernameEq(), ageEq() 처럼 말이다.
이럼 이제 두 메서드를 만들어 보자.
1
2
3
4
5
6
7
8
private BooleanExpression usernameEq(String usernameCond) {
if (usernameCond != null)
return member.username.eq(usernameCond);
return null;
}
private BooleanExpression ageEq(Integer ageCond) {
return ageCond != null ? member.age.eq(ageCond) : null;
}
둘 다 같은 기능이지만 하나는 if문 하나는 삼항 연산자를 사용했다.

결과도 내가 예상한 것처럼 잘 나온다.
이렇게 메서드로 빼면 또 장점이 있다.
메서드 끼리 또 조합이 가능하다는 거다.
1
2
3
private BooleanExpression allEq(String usernameCond, Integer ageCond) {
return usernameEq(usernameCond).and(ageEq(ageCond));
}
그럼 쿼리는 다음과 같이 바뀐다.
1
2
3
4
5
6
private List<Member> searchMember2(String usernameCond, Integer ageCond) {
return queryFactory
.selectFrom(member)
.where(allEq(usernameCond, ageCond))
.fetch();
}
정말 MyBatis나 다른 곳에선 상상도 못한 생각인 것 같다. 메서드를 합치다니
물론 Null 처리는 어떻게 해야 하긴 할 것이다.
결론
where조건에null값은 무시된다.- 메서드를 다른 쿼리에서도 재활용 할 수 있다.
- 쿼리 자체의 가독성이 높아진다.
조합 할 때 주의
null체크는 주의해서 처리해야 함.
댓글남기기