QueryDsl의 동적 쿼리를 해결하는 방식
기본적으로 쿼리를 동적으로 사용한다는 의미는
파라미터의 값이 Null이냐 아니냐
에 따라 동적으로 쿼리가 작성이 되는게 목적이다.
ex) 검색조건에서 많이 사용되는 것들`
1.BooleanBuilder 사용하기
2.where절에 다중 파라미터 사용하기
BooleanBuilder 사용
package com.querydsl.core BooleanBuilder
사용한다.
BooleanBuilder는 두개의 생성자를 가지고 있다.
최초 선언에 Predicate를 선언할 수 있는데, 생성하면서 null이면 안되는
Param들을 미리 선언해주면 된다.
/**
* Create an empty BooleanBuilder
*/
public BooleanBuilder() { }
/**
* Create a BooleanBuilder with the given initial value
*
* @param initial initial value
*/
public BooleanBuilder(Predicate initial) {
predicate = (Predicate) ExpressionUtils.extract(initial);
}
@Test
public void dynamicQuery_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 usernameParam, Integer ageParam) {
*******************************************************************************
//1번. default Builder 생성으로 구현
BooleanBuilder builder = new BooleanBuilder();
if(usernameParam != null){
builder.and(member.username.eq(usernameParam));
}
if(ageParam != null){
builder.and(member.age.eq(ageParam));
}
*********************************************************************************
*********************************************************************************
//2번. Builder 초기값 삽입으로 구현 (member.username이 필수값인 경우)
BooleanBuilder builder = new BooleanBuilder(member.username.eq("member1"));
if(ageParam != null){
builder.and(member.age.eq(ageParam));
}
**********************************************************************************
return queryFactory.selectFrom(member)
.where(builder)
.fetch();
}
- 💥builder도 and, or 등 추가 where 연산이 가능하다.
💫동적쿼리 where 다중 파라미터로 처리하기
앞서서
장점
- Main query를 깔끔하게 유지하고, 명시성이 좋다.
- BooleanExpression을 반환하여 새로운 조건들을 조합해서 사용할 수 있다. ex) 나이가 40이상, 이름 xx는 이벤트 대상자
- 재사용성이 좋다.
BooleanExpression은 queryDsl에서 Predicate를 구현한 구현체이다
public abstract class BooleanExpression extends LiteralExpression<Boolean> implements Predicate
where절 안에 들어갈 true,false 값을 param에 따라 메서드로 추출하여 제작한다.
- 📀 queryFactory의 where절에서 null이 들어가면 자동으로 skip으로 간주하기 때문에 동적 쿼리가 가능하다.
ex) return queryFactory
.selectFrom(member)
.where(null, ageEq(ageParam))
.fetch();
- 위 상황에서는 age만 같은지 체크함
기본 코드
@Test
public void dynamicQuery_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 usernameParam, Integer ageParam) {
return queryFactory
.selectFrom(member)
*******************************************************************************
.where(usernameEq(usernameParam), ageEq(ageParam)) //where 절에 메서드를 제작해 동작. (Predicate만 받으면 된다)
*******************************************************************************
.fetch();
}
where Param별 조건 메서드 생성
private BooleanExpression ageEq(Integer ageParam) {
return ageParam != null ? member.age.eq(ageParam) : null;
}
private BooleanExpression usernameEq(String usernameParam) {
return usernameParam != null ? member.username.eq(usernameParam) : null;
}
- null은 skip하는 queryFactory의 where 조건절의 특성을 이용해 그냥 null을 리턴한다.
이 true,false만 지켜주면 어떤 메서드든 조합하여 만들 수 있다.
private BooleanExpression allEq(String usernameParam, Integer ageParam){
return usernameEq(usernameParam).and(ageEq(ageParam));
}
- usernameEq + ageEq를 조합해서 allEq를 만든 모습
private List<Member> searchMember3(String usernameParam, Integer ageParam) {
return queryFactory
.selectFrom(member)
.where(allEq(usernameParam,ageParam))
.fetch();
}
- 극한으로 깔끔해졌다.
'스프링 > QueryDsl' 카테고리의 다른 글
[QueryDsl] sqlFunction 사용하기 (0) | 2022.03.13 |
---|---|
[QueryDsl] 벌크 update,delete (0) | 2022.03.13 |
[QueryDsl] Projection(select에서 뭘 가져올까?)종류에 따른 결과 반환 (Tuple, Dto로 반환)하는 법 (0) | 2022.03.11 |
[QueryDsl] Case문, 상수 출력, 특정 문자값 붙여 출력하기 (0) | 2022.03.10 |
[QueryDsl] 서브쿼리 사용하기 (0) | 2022.03.10 |