[QueryDSL] BooleanExpression을 통한 복잡한 동적쿼리 표현(BooleanBuilder 제거)
- DB접근기술/JPA
- 2021. 2. 13. 11:47
안녕하세요.
오늘은 BooleanExpression을 통해서 QueryDSL Repository의 표현을 좀더 직관적으로 볼 수 있도록 리팩토링하는 과정을 소개해보고자 합니다.
사실 이부분에 대해서는 그동안 BooleanBuilder라는 객체를 활용해서 where 절에 들어올 쿼리문을 생성했는데요.
여러 if절에 의해 다음과 같이 쿼리의 형태를 전혀 예상할 수 없을 정도로 바뀌었습니다.
BooleanBuilder를 활용한 repository 메소드
public List<Study> findLiveStudyBySearch(String title, Integer bigCity, Integer smallCity) {
BooleanBuilder builder = new BooleanBuilder();
if (StringUtils.isNotBlank(title)) { // 제목 검색
builder.and(study.title.contains(title));
}
if (bigCity != null) { // 시도 검색
builder.and(study.bigCity.eq(bigCity));
}
if (smallCity != null) { // 시군구 검색
builder.and(study.smallCity.eq(smallCity));
}
builder.and(study.deleted.eq(false)); // 삭제여부 false
return jpaQueryFactory.selectFrom(study)
.where(builder)
.fetch();
}파라미터로 넘어온 title, bigCity, smallCity라는 검색조건의 유무에 따라 if절에서 조건을 따로 넣어주는 형태로 할 수 밖에 없었는데요.
BooleanExpression을 활용하면 어떻게 변할수 있는지 확인해 보시죠!!
BooleanExpression을 활용한 리팩토링
public List<Study> findLiveStudyBySearch(String title, Integer bigCity, Integer smallCity) {
return jpaQueryFactory.selectFrom(study)
.where(eqTitle(title),
eqBigCity(bigCity),
eqSmallCity(smallCity),
eqDeleted(false))
.fetch();
}- eqTitle, eqBigCity, eqSmallCity, eqDeleted 라는 메소드를 추가적으로 생성하여 BooleanExpression 타입을 리턴하도록 합니다.
- 결과적으로 코드는 길어졌지만 만약 재사용성까지 고려한다면 기꺼이 하지 않을 이유가 없어보입니다.
- 또한 한순간에 study라는 도메인에서 title, bigCity, smallCity, deleted 라는 컬럼의 검색이 이루어진다는 것을 파악할 수 있습니다.
아래는 추가적으로 정의한 BooleanExpression 타입을 리턴하는 메소드입니다.
private BooleanExpression eqTitle(String title) {
if (StringUtils.isBlank(title)) {
return null;
}
return study.title.containsIgnoreCase(title);
}
private BooleanExpression eqBigCity(Integer bigcity) {
if (bigcity != null) {
return null;
}
return study.bigcity.eq(bigcity);
}
private BooleanExpression eqSmallCity(Integer smallCity)
if (smallCity != null) {
return null;
}
return study.smallCity.eq(smallCity);
}
private BooleanExpression eqDeleted(boolean deleted) {
return study.deleted.eq(deleted);
}
해당 QueryDSL에 대한 내용은 우아콘2020에서 확인할 수 있는 내용입니다. 저 또한 해당 영상을 통해서 많은 부분을 배웠기 때문에 공유드립니다.
감사합니다.
'DB접근기술 > JPA' 카테고리의 다른 글
| JPA Entity 클래스에 Enum 타입 사용기 AttributeConverter 활용(응용) (0) | 2021.08.07 |
|---|---|
| JPA Entity 클래스에 Enum 타입 사용기 @Enumerated, AttributeConverter 활용(기본) (0) | 2021.08.01 |
| [Spring Data JPA] save와 saveAll의 성능 차이에 대한 실험과 결과!(스프링 프록시, @Transactional) (0) | 2021.02.07 |
| [JPA] 공통 컬럼 @MappedSuperClass를 이용하여 상속받기 (3) | 2020.08.18 |
| [JPA] H2 Database 사용시 ApplicationRunner를 이용하여 테스트 데이터 미리 넣어두는 방법. (0) | 2020.08.09 |