동적 쿼리를 해결하는 2가지 방법
- BooleanBuilder
- Where 다중 파라미터 사용
(1) BooleanBuilder 방식
BooleanBuilder를 만들어서 querydsl의 where절에 넣어주기만 하면된다.
BooleanBuilder를 만들 때, 한 조건이 null이면 해당 조건을 빼도록 구현한다.
따라서 usernameParam을 null로 두었을 때는, JPQL의 where절에 age만 존재하고,
@Test
public void dynamicQuery_boolean_builder() {
String usernameParam = null;
Integer ageParam = 10;
List<Member> result = searchMember1(usernameParam, ageParam);
Assertions.assertThat(result.size()).isEqualTo(2);
}
private List<Member> searchMember1(String usernameParam, Integer ageParam) {
BooleanBuilder builder = new BooleanBuilder();
if(usernameParam != null) {
builder.and(member.username.eq(usernameParam));
}
if(ageParam != null) {
builder.and(member.age.eq(ageParam));
}
return queryFactory.selectFrom(member).where(builder).fetch();
}
두 조건 모두 null이 아닐 때는 where절에서 username, age를 모두 비교하는 것을 볼 수 있다.
@Test
public void dynamicQuery_boolean_builder() {
String usernameParam = "member1";
Integer ageParam = 10;
List<Member> result = searchMember1(usernameParam, ageParam);
Assertions.assertThat(result.size()).isEqualTo(1);
}
private List<Member> searchMember1(String usernameParam, Integer ageParam) {
BooleanBuilder builder = new BooleanBuilder();
if(usernameParam != null) {
builder.and(member.username.eq(usernameParam));
}
if(ageParam != null) {
builder.and(member.age.eq(ageParam));
}
return queryFactory.selectFrom(member).where(builder).fetch();
}
(2) Where 다중 파라미터 활용
querydsl의 where절에 다중파라미터를 넣어 여러 조건을 처리할 수 있다.
아래 코드와 같이, 조건이 없을 때는 null을, 조건이 있을 때는 조건이 일치하는지 여부를 리턴해주는 메서드를 만들고
그 메서드를 where절에 파라미터로 넣어주면 다중 조건을 처리할 수 있다. (파라미터가 null이라면 그 조건은 무시된다.)
private List<Member> searchMember2(String usernameCond, Integer ageCond) {
return queryFactory
.selectFrom(member)
.where(usernameEq(usernameCond), ageEq(ageCond))
.fetch();
}
private Predicate usernameEq(String usernameCond) {
return usernameCond == null ? null : member.username.eq(usernameCond);
}
private Predicate ageEq(Integer ageCond) {
return ageCond == null ? null : member.age.eq(ageCond);
}
동적 쿼리에서의 querydsl의 장점
querydsl의 진정한 장점은, 여러 동적쿼리 조건을 조합할 수 있고 재활용할 수 있다는 것이다.
아래 코드는 이름을 비교하는 메서드인 usernameEq, 나이를 비교하는 메서드인 ageEq를 각각 만들어, isSame이라는 메서드 안에서 and 조건을 조합한 예시이다.
이 isSame을 querydsl 코드의 where 조건 안에 넣으면, 이름과 나이가 같은 사람을 조회하는 쿼리가 나가지만, where절 안에 긴 코드가 들어가는 것보다 훨씬 가독성이 좋다.
그리고 이렇게만든 isSame 메서드는 다른 querydsl where절 안에서 재활용도 가능하다.
private List<Member> searchMember2(String usernameCond, Integer ageCond) {
return queryFactory
.selectFrom(member)
.where(isSame(usernameCond, 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);
}
private BooleanExpression isSame(String usernameCond, Integer ageCond) {
return usernameEq(usernameCond).and(ageEq(ageCond));
}
Reference
'개념 공부 > Spring & ORM' 카테고리의 다른 글
[ Java / querydsl ] Queryds에서의 페이지네이션 (1) | 2025.03.29 |
---|---|
[Spring / Jpa / querydsl ] 커스텀 리포지토리 구조 (0) | 2025.03.23 |
[Java / querydsl] 여러 Projection 방법 (0) | 2025.03.16 |
[Java / Spring] @Transational과 ChainedTransactionManager (0) | 2025.03.12 |
[JPA 개념] 연관 관계 매핑 (2) | 2024.06.06 |