-
[Spring] Querydsl 동적 쿼리Framework/Spring 2022. 3. 4. 22:22
이번에는 Querydsl로 동적 쿼리를 작성하여 다양한 상황에 대응하는 법에 대해서 알아보고자 한다.
jpa나 querydsl을 사용하기 전에는 si업계를 주름잡고 있는 mybatis를 사용했었다.
mybatis에서도 동적쿼리를 작성할 수는 있지만 읽기가 굉장히 복잡했었다. 그렇기에 querydsl을 통해서 동적쿼리를 익혀서 어려운 쿼리에 대응해보도록 하자.
우선 동적쿼리를 작성하는 방법은 2가지이다.
- BooleanBuilder사용
- BooleanExpression을 통한 메소드 사용
우선 1번부터 알아보도록 하자.
QMember member = new QMember(); void dynamicQuery_BooleanBuilder() { String username = "member1"; Integer age = null; List<Member> result = searchMember(usernameParam, ageParam); } private List<Member> searchMember(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(); }
searchMember 메소드를 보면 파라미터를 2가지를 받는 것을 알 수 있다.
파라미터 값이 주어지게 되면 이를 토대로 BooleanBuilder를 통해서 .and()를 통해서 select절에 넣을 값을 완성 할 수 있다.
null처리를 하는 부분이 조금 마음에 안들기는 하지만 그래도 코드의 가독성은 mybatis에서 작성하는 것보다는 좋아보인다.
그 다음으로 BooleanExpression을 통한 방법을 알아보도록 하자.
void dynamicQuery_WhereParam() { String usernameParam = "member1"; Integer ageParam = null; List<Member> result = searchMember(usernameParam, ageParam); assertThat(result.size()).isEqualTo(1); } private List<Member> searchMember(String usernameCond, Integer ageCond) { return queryFactory .selectFrom(member) .where(allEq(usernameCond, ageCond)) .fetch(); } private BooleanExpression usernameEq(String usernameCond) { return usernameCond != null ? member.username.eq(usernameCond) : null; } private BooleanExpression ageEq(Integer ageCond) { return ageCond != null ? member.age.eq(ageCond) : null; } private BooleanExpression allEq(String usernameCond, Integer ageCond){ return usernameEq(usernameCond).and(ageEq(ageCond)); }
일단 selectMember함수 자체만으로 쿼리를 읽기 쉽도록 분리되어 작성되었고, 분리된 allEq, ageEq, usernameEq함수들이 짜임새 있도록 작성된 것을 알 수 있다.
특히나 allEq함수의 리턴하는 값을 보게 되면 마치 레고처럼 조립이 가능한 모양새로 구성되어있다. 그렇기 때문에 "코드의 양"자체는 늘어났지만 이는 추후 확장성 있도록 분리한 상태이다. select하는 조건이 변경될 경우 다른 함수의 수정은 건들필요 없이 오로지 allEq함수만 수정하면 된다!
이번에는 querydsl을 통하여 동적쿼리를 작성할 수 있는 방법에 대해서 알아보았는 데, 아직 복잡한 비즈니스 로직이 녹여져 있는 쿼리를 작성해보진 않아서 좀 더 복잡해질 경우 어떻게 처리해야할지에 대해서는 알아보지 못했다. 다음에는 좀 더 복잡한 예제로 querydls의 효용성을 느껴봐야겠다.
'Framework > Spring' 카테고리의 다른 글
[Spring] Domain time mapping (0) 2022.04.25 [Spring] request에서 enum으로 값 전달받기 (0) 2022.03.15 [Spring] QueryDsl projection(2) (0) 2022.03.02 [Spring] QueryDsl projection (0) 2022.03.01 [SpringBoot] Jackson Annotation (0) 2020.08.17