BooleanBuilder
사용 ]📌 동적 쿼리를 해결하는 두 가지 방식
BooleanBuilder
Where
다중 파라미터 사용
BooleanBuilder
사용@Test
public void 동적쿼리_BooleanBuilder() throws Exception {
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();
}
BooleanBuilder
를 통한 동적 쿼리 생성은 빌더를 생성 후 필요한 조건을 null
확인 여부에 따라 and
또는 or
등으로 더해주면 된다.
Where
다중 파라미터 사용 ]Where
다중 파라미터 사용@Test
public void 동적쿼리_WhereParam() throws Exception {
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))
.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;
}
Where
조건에 null
값은 무시된다.usernameEq()
와 같은 메서드를 다른 쿼리에서도 재활용할 수 있다.private BooleanExpression allEq(String usernameCond, Integer ageCond) {
return usernameEq(usernameCond).and(ageEq(ageCond));
}
method chaining
가능null
체크는 주의해서 처리해야 한다.long count = queryFactory
.update(member)
.set(member.username, "비회원")
.where(member.age.lt(28))
.execute();
long count = queryFactory
.update(member)
.set(member.age, member.age.add(1))
.execute();
곱하기는 multiply(x)
사용 → Ex. member.age.multiply(2)
long count = queryFactory
.delete(member)
.where(member.age.gt(18))
.execute();
🚫 주의 ❗
JPQL 배치와 마찬가지로, 영속성 컨텍스트에 있는 엔티티를 무시하고 실행되기 때문에 배치 쿼리를 실행하고 나면 영속성 컨텍스트를 초기화하는 것이 안전하다.
SQL function
호출하기 ]JPA와 같이
Dialect
에 등록된 내용만 호출할 수 있다.
replace
함수String result = queryFactory
.select(Expressions.stringTemplate("function('replace', {0}, {1}, {2})", member.username, "member", "M"))
.from(member)
.fetchFirst();
member
가 M
으로 변경된다.
lower
함수String result = queryFactory
.select(member.username)
.from(member)
.where(member.username.eq(Expressions.stringTemplate("function('lower', {0})", member.username)))
lower
같은 ansi
표준 함수들은 querydsl이 대부분 내장하고 있기 때문에 다음과 같이 처리해도 결과는 같다.
.where(member.username.eq(member.username.lower()))