입력값이나 특정 상황에 따라 쿼리문이 변경될 수 있는 쿼리
/**
* 동적 쿼리 - BooleanBuilder 사용
*/
@Test
public void 동적쿼리_BooleanBuilder() throws Exception {
String usernameParam = "member1";
Integer ageParam = null;
List<Member> result = searchMember1(usernameParam, ageParam);
assertThat(result.size()).isEqualTo(1);
}
BooleanBuilder 사용해서 쿼리 날리고 결과 받아오는 함수
BooleanBuilder로 동적 쿼리 만들기
1. BooleanBuilder 인스턴스 생성
BooleanBuilder builder = new BooleanBuilder();2. builder.and(), builder.or()로 조건 연결
ex)
builder.and(member.username.eq(usernameCond));3. queryFactory의 where의 파라미터로 builder 인스턴스 넘기기
/**
* 파라미터의 null 여부에 따라서 쿼리가 동적으로 바뀌어야함.
*/
private List<Member> searchMember1(String usernameCond, Integer ageCond) {
BooleanBuilder builder = new BooleanBuilder();
// BooleanBuilder builder = new BooleanBuilder(member.username.eq(usernameCond)); // 초기값 설정도 가능. username은 필수라서 null이 들어오지 않는 경우.
if(usernameCond != null){// usernameCond가 null이 아니면
builder.and(member.username.eq(usernameCond)); // builder에 and 조건 추가
}
if(ageCond != null){// ageCond가 null이 아니면
builder.and(member.age.eq(ageCond));// builder에 and 조건 추가
}
return queryFactory
.selectFrom(member)
.where(builder) // where에 builder
.fetch();
}
파라미터 바인딩 둘다 되고, where절에 두개의 조건 and로 연결

where절을 보면 username만 조건으로 들어감

- 강사님 추천
- where 조건에 null 값은 무시됨
- 아래에서 소개하는
usernameEq,ageEq함수에서 들어온 값이 null이면 null을 반환- where절에 여러개의 파라미터가 사용될 경우, 각 조건들 and 조건으로 묶이고, null값이면 무시
장점
- 만든 메서드를 다른 쿼리에서도 재사용이 가능
- 쿼리 가독성이 높아짐
각 함수 소개
동적쿼리_WhereParam(): searchMember2로 username, age를 넘겨서 동적 쿼리를 실행하도록 함searchMember2: queryFactory에서 where절 파라미터로usernameEq,ageEq함수의 반환 값을 넘김usernameEq: 이름을 파라미터로 받아서 null 이아니면 조건식을 반환ageEq: 나이를 파라미터로 받아서 null 이아니면 조건식을 반환
/**
* 동적 쿼리 - Where 다중 파라미터 사용
* 김영한 선생님이 실무에서 좋아하신다고 하심!
* BooleanBuilder보다 깔끔
*/
@Test
public void 동적쿼리_WhereParam() throws Exception {
String usernameParam = "member1";
Integer ageParam = null;
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: 파라미터에 null이 들어오면 무시
// .where(allEq(usernameCond, ageCond)) // 두개 다 조립해서 결과 받는 함수 사용도 가능
.fetch();
}
private BooleanExpression usernameEq(String usernameCond) {
return usernameCond != null ? member.username.eq(usernameCond) : null; // if-else 간단해서 삼항연산자 사용
}
private BooleanExpression ageEq(Integer ageCond) {
return ageCond != null ? member.age.eq(ageCond) : null;
}
위에서 정의했던
usernameEq,ageEq함수의 반환 값을.and()로 묶은 조건식을 반환하는allEq함수
// 조립 가능, 재사용도 가능
private BooleanExpression allEq(String usernameCond, Integer ageCond){
return usernameEq(usernameCond).and(ageEq(ageCond));
}