동적 쿼리를 해결하는 방법은 두 가지가 있다.
1. BooleanBuilder
2. Where
다중 파라미터 사용 (where 문 안에 여러 파라미터를 넣는 방법)
아래의 코드는 그 중 BooleanBuilder를 사용하는 방법의 예시이다.
@Test
public void dynamicQuery_BooleanBuilder() {
String usernameParam = "member1";
Integer ageParam = 10;
List<Member> result = searchMember1(usernameParam, ageParam);
assertThat(result.size()).isEqualTo(1);
}
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();
}
이 방법은 강사님이 실무에서 정말 좋아하는 방법이다🙃 (코드가 깔끔해짐)
@Test
public void dynamicQuery_WhereParam() {
String usernameParam = "member1";
Integer ageParam = 10;
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))
// .where(allEq(usernameCond, ageCond)) // 이렇게까지 깔끔해질 수 있음
.fetch();
}
private BooleanExpression usernameEq(String usernameCond) { // 장점: 재사용 가능
if(usernameCond == null) {
return null;
} else {
return member.username.eq(usernameCond);
}
// return usernameCond == null ? null : member.username.eq(usernameCond);
// 위 코드처럼 간단할 때는 이렇게 삼항 연산자를 사용하는 것도 좋다.
}
private BooleanExpression ageEq(Integer ageCond) { // 장점: 재사용 가능
return ageCond != null ? member.age.eq(ageCond) : null;
// ageCond가 null이 아니면 member.age.eq(ageCond), null이면 null
}
private Predicate allEq(String usernameCond, Integer ageCond) {
return usernameEq(usernameCond).and(ageEq(ageCond));
}
where
조건에 null 값은 무시그리고 위의 코드를 보면 알 수 있듯 allEq
메소드처럼 조합해서도 가능하다.
이때, null 체크는 주의해 처리해주어야 한다.