2 분 소요

인프런 실전! 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() 메서드는 이름과 나이를 받아 리스트를 반환해주는 메서드이다.

이제 searchMember1BooleanBuilder 사용하여 만들어 보자.

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 체크는 주의해서 처리해야 함.

태그: ,

카테고리:

업데이트:

댓글남기기