조건관련 작업시 아래처럼 엔티티별 별도의 Predicate를 사용하기는 하는데 가끔 보기 싫을 때가 있다.
기존에는 아래처럼 조건을 별도로 구분해서 나눈 후, allOf로 조합처리 했는데.
public static Predicate containsBrandName(BrandFindCondition condition) {
BooleanBuilder builder = new BooleanBuilder();
if (!StringUtils.isEmpty(condition.getBrandName())) {
builder.and(qBrandEntity.brandName.contains(condition.getBrandName()));
}
return builder;
}
public static Predicate containsBrandCode(BrandFindCondition condition) {
BooleanBuilder builder = new BooleanBuilder();
if (!StringUtils.isEmpty(condition.getBrandCode())) {
builder.and(qBrandEntity.brandCode.contains(condition.getBrandCode()));
}
return builder;
}
막 사용하다 보면 이런식으로 사용되어지고 있게 되어서...
public static Predicate whereAll(BrandFindCondition condition) {
BooleanBuilder builder = new BooleanBuilder();
if (!StringUtils.isEmpty(condition.getBrandName())) {
builder.and(qBrandEntity.brandName.contains(condition.getBrandName()));
}
if (!StringUtils.isEmpty(condition.getBrandCode())) {
builder.and(qBrandEntity.brandCode.contains(condition.getBrandCode()));
}
if ( .....
return builder;
}
이거나 저거나 if 조건이 자꾸 늘어나서 아타까움(optional로 걸어봐야 그게 그거). 물론 별도 Predicate를 만든 후라 Repository나 Service는 깔끔하게 보이기는 하는데..
해서, 비교 확인차 우선 Builder를 만들어 추가해 보기로 함.
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class WhereClauseBuilder {
private List<Predicate> predicateBuilders = new ArrayList<>();
public static WhereClauseBuilder builder() {
return new WhereClauseBuilder();
}
public WhereClauseBuilder and(Predicate predicate) {
predicateBuilders.add(predicate);
return this;
}
public Predicate build() {
return ExpressionUtils.allOf(predicateBuilders);
}
public WhereClauseBuilder like(StringPath path, String value) {
if (StringUtils.isEmpty(value)) {
return this;
}
predicateBuilders.add(path.contains(value));
return this;
}
public WhereClauseBuilder eq(StringPath path, String value) {
if (StringUtils.isEmpty(value)) {
return this;
}
predicateBuilders.add(path.eq(value));
return this;
}
public WhereClauseBuilder eq(BooleanPath path, Boolean value) {
predicateBuilders.add(path.eq(value));
return this;
}
public WhereClauseBuilder eqId(NumberPath<Long> path, Long value) {
if (Objects.isNull(value)) {
return this;
}
predicateBuilders.add(path.eq(value));
return this;
}
}
사용할때는 이런식.
public List<BrandEntity> findAll(BrandFindCondition condition) {
return from(qBrandEntity).where(
WhereClauseBuilder.builder()
.like(qBrandEntity.brandName, condition.getBrandName())
.eq(qBrandEntity.brandCode, condition.getBrandCode())
.build()
).fetch();
}
숫자의 경우에는 Enum처리를 했는데.. 제너릭으로 WhereClauseBuilder에서 처리해야 하나 고민 스럽.. 뭐 따로빼서 처리.
.and(NumberClausePredicate.GT.compare(qBrandEntity.price, price))
딱히 뭐가 이뻐졌는지는 모르겠...엔티티별 별도의 Predicate를 두고 하나하나 조건을 만든후에 allOf를 하는게 더 명시적이고 유지보수가 쉬울꺼 같기도하고.. 아닌거 같기도 하고.. Null이 참 그러네..ㅎㅎ
좀 더 작업해 보다가 결정해야겠다. 이런거 고민 할 시간에 서비스 하나 후딱 만들어서 돈벌게 되면 더 좋은 개발자를 데려와서 고쳐주십...콜록콜록..켁켁..