[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 |