728x90
반응형
0. 이 글의 목적
BooleanExpression을 쓰는 게 best practice일 수 있지만 더 심플한 방법을 찾다 보니 가능한 방법을 찾아서 메모 겸 적어두고자 함
1. 상황
querydsl을 이용해 db에서 데이터를 가져오려고 하는데 where조건을 동적으로 해야할 일이 생김
e.g.
//회사 로직을 제거하기 위해 최대한 단어를 추상화함
queryFactory
.from(dataEntity)
.groupBy(dataEntity.column1)
.select(
dataEntity.column1,
dataEntity.column2.as("tmp"),
dataEntity.column3
)
.where(dataEntity.column1.between(
requestCondition.condition1(),
requestCondition.condition2()
),
requestCondition.column3.eq(requestCondition.condition3()))
.fetch();
이렇게 보면 문제가 없다.
근데 만약에 requestCondition의 condtion3로 들어온 데이터가 null인 경우 where절에서 문제가 발생한다.(select에서는 null이면 빈 값이 들어오니 상관이 없다.)
이런 식으로 동적으로 해결해야 하는 경우 보통 BooleanExpression을 사용하라고 하지만 좀 더 심플하게 해결해보고자 했다.
2. 과정
where문은 어떤 걸 받고 뭘 리턴할까
Q는 와일드카드고 o는 변수이름이니까 Predicate에 집중하면 된다.
그러면 우리가 일반적으로 사용하던 값들은 뭘 리턴하고 있을까
between은 BooleanExpression을 리턴하고 BooleanExpression은 Predicate타입이라고 한다.
그러면 우리는 결국 잘 정리해서 Predicate[]로 리턴해주면 where절이 가변인자로 받으니까 잘 처리해 줄 것이다.
3. 결론적으로 코드는
private Predicate[] getWhereCondition(QEntity dataEntity, RequestCondition requestData){
List<Predicate> conditionList = new ArrayList<>();
conditionList.add(dataEntity.ts.between(requestData.column1(), requestData.column2()));
if(StringUtils.hasText(requestData.column3())){
conditionList.add(dataEntity.column3.eq(requestData.column3()));
}
return conditionList.toArray(new Predicate[0]);
}
queryFactory
.from(dataEntity)
.groupBy(dataEntity.column1)
.select(
dataEntity.column1,
dataEntity.column2.as("tmp"),
dataEntity.column3
)
.where(getWhereCondition(dataEntity, requestData)
.fetch();
이렇게 바꿀 수 있다.
생각보다 심플해졌다.
4. 결론
BooleanExpression도 좋지만 더 상위 계층해서 추상화해서 사용해도 괜찮지 않을까
728x90
반응형
'JAVA > spring' 카테고리의 다른 글
spring method 요청에 대해 핸들링하기 (0) | 2023.03.13 |
---|---|
spring boot 최소한으로 logging 설정하기(logback을 곁들인) (0) | 2023.03.12 |
Flyway Placeholder사용(application.yml / properties 파일 읽기) (0) | 2023.02.26 |
spring(boot)의 예외 처리 방식 (0) | 2023.02.24 |
자바 ORM 표준 JPA 프로그래밍 - 기본편 끄적끄적 (1) (0) | 2023.01.15 |