설정한 검색 조건
키워드 검색(일반적인 검색어)
=> 지금은 Like 문을 활용했는데 이후 검색 성능 향상을 위해 index나 full Text Index를 적용 해볼것이다. (+ Elasic Search)
카테고리, 가격 대, 오픈런 유무 필터 검색
가격대, 관심 상품 순 , 오픈런 시작 시작 시간 순 정렬
public interface ProductRepositoryCustom {
Page<AllProductResponseDto> searchAllProducts(ProductSearchCondition condition, Pageable pageable);
}
@RequiredArgsConstructor
public class ProductRepositoryImpl implements ProductRepositoryCustom{
private final JPAQueryFactory queryFactory;
@Override
public Page<AllProductResponseDto> searchAllProducts(ProductSearchCondition condition, Pageable pageable)
쿼리문 분석
1) 생성자 방식의 Projection을 택하였다. (Record로 Dto를 만들어서 생성자 방식밖에 지원해주지 않았음)
List<AllProductResponseDto> content = queryFactory
.select(Projections.constructor(AllProductResponseDto.class,
product.id,
product.productName,
product.productImage,
product.price,
product.mallName,
product.currentQuantity,
product.eventStartTime,
product.category,
product.totalQuantity,
product.wishCount
)).from(product)
2) 위에서 말한 조건문을 생성한다 .
키워드 검색(일반적인 검색어)
카테고리, 가격 대, 오픈런 유무 필터 검색
BooleanBuilder 방식 대신에 쿼리문을 추가로 작성할 것과 코드의 가독성을 위해 Where 조건문 방식을 택했다.
.where(
keywordContains(condition.getKeyword()),
categoryEq(condition.getCategory()),
isOpenRunEq(condition.getStatus()),
isPriceBetween(condition.getLprice(), condition.getGprice())
)
각각의 매서드에서 조건문을 정의하고 where 문에 조건으로 준다.
< keywordContains >
private BooleanExpression keywordContains(String keyword) {
return hasText(keyword) ? product.productName.contains(keyword).or(product.mallName.contains(keyword)) : null;
}
< categoryEq >
private BooleanExpression categoryEq(String category) {
return hasText(category) ? product.category.eq(category) : null;
}
}
< isOpenRunEq >
private BooleanExpression isOpenRunEq(OpenRunStatus status) {
if( status == null){
return null;
}
return hasText(status.toString()) ? product.status.eq(status) : null;
}
< isPriceBetween >
private BooleanExpression isPriceBetween(Integer lprice, Integer uprice) {
if (lprice == null && uprice == null){
return null;
}else if(lprice == null){
return product.price.loe(uprice);
}else if(uprice == null){
return product.price.goe(lprice);
}
return product.price.between(lprice, uprice);
}
< sortMethod >
private OrderSpecifier<?> sortMethod(String sortBy, Boolean isAsc) {
if(isAsc ==null){
isAsc = true;
}
if(sortBy == null){
return product.id.desc();
}
switch(sortBy){
case "price" -> {
return (isAsc == true) ? product.price.asc() : product.price.desc();
}
case "eventStartTime" -> {
return (isAsc == true) ? product.eventStartTime.asc() : product.eventStartTime.desc();
}
case "wishCount" -> {
return (isAsc == true) ? product.wishCount.asc() : product.wishCount.desc();
}
default -> {
return product.id.desc();
}
}
}
public interface ProductRepository extends JpaRepository<Product, Long>,ProductRepositoryCustom
좋은 글 감사합니다. 자주 방문할게요 :)