
BooleanBuilder
public void dynamicQuery_BooleanBuilder() {
String usernameParam = "member1";
Integer ageParam = 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();
}
BooleanBuilder 객체를 생성하고 if문을 돌며 builder에 Querydsl 문법에 맞게 조건을 추가한다.
그렇게 만들어진 builder를 최종적으로 쿼리문의 where절에 넣기만 하면 끝이다.
아래 처럼 new BooleanBuilder() 안에 초기 조건을 넣을 수도 있다.
new BooleanBuilder(member.username.eq(usernameCond));
null로 반환된 값들은 where절에서는 NPE 오류 없이 무시되므로 걱정하지 않아도 된다.
BooleanBuilder 방식은 사용하기는 쉬우나, 단점으로는 메서드를 보지 않고 쿼리문만 봐서는 이해가 되질 않는다.
바로 밑에서 BooleanBuilder 사용 없이 where절 안에 메서드를 넣는 방식으로 이 부분을 개선해보자.
where절에 메서드 넣기
public void dynamicQuery_WhereParam() {
String usernameParam = "member1";
Integer ageParam = null;
List<Member> result = searchMember(usernameParam, ageParam);
}
private List<Member> searchMember(String usernameCond, Integer ageCond) {
return List<Member> result = queryFactory
.selectFrom(member)
.where(usernameEq(usernameCond), ageEq(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;
}
추천하는 방식이다.
BooleanExpression 타입의 반환값을 갖는 조건메서드를 만들다.
각 메서드 안에서는 Querydsl 문법에 맞게 where절에 들어갈 로직을 만들어주면 된다.
마찬가지로 null이 반환될 경우 where절 안에서 무시되므로 신경쓰지 않아도 된다.
BooleanBuilder와 비교했을 때 가장 큰 장점으로는, where절 안에 메서드 이름만 봐도 쿼리 동작을 유추하기 쉽다.
private List<Member> searchMember2(String usernameCond, Integer ageCond) {
List<Member> result = queryFactory
.selectFrom(member)
.where(allEq(usernameCond, ageCond)) // 메서드 조립 가능
.fetch();
for (Member member1 : result) {
System.out.println("member1 = " + member1);
}
return result;
}
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) {
// 이 경우는 곧바로 where절로 가는게 아니므로 null 체크를 해줘야함
if (usernameCond == null && ageCond == null) {
return null;
} else if (ageCond == null) {
return usernameEq(usernameCond);
} else if (usernameCond == null) {
return ageEq(ageCond);
} else {
return usernameEq(usernameCond).and(ageEq(ageCond));
}
}
이런 식으로 where절 안에 들어가는 메서드를 조립할 수도 있다.
단, 이 경우에는 곧바로 where절로 반환되는 게 아니기 때문에 null 처리를 해주지 않으면 NPE 오류가 발생하니 주의하자.
'스프링' 카테고리의 다른 글
mustache 템플릿 설정 (0) | 2022.11.18 |
---|---|
[자바] Lombok - 부모클래스의 toString 호출하기 (0) | 2022.11.17 |
[스프링] @RestControllerAdvice 이용한 예외처리 방법 (0) | 2022.10.14 |
[스프링] 톰캣(Tomcat) 서버 시작 속도 개선 (2) | 2022.10.06 |
[스프링] 접속 IP 주소 IPv4 형태로 가져오기 (인텔리제이) (0) | 2022.10.06 |