2024.03.22
[테킷 백엔드] 프로젝트 - alcoholfriday
환경 - 스프링부트 3.2.1, 자바 JDK17
작업 - 상품 검색
String[]
의 length는 1이다.// 카테고리 검색 조건 생성
BooleanExpression categoryPredicate = categories.isEmpty()
? item.isNotNull() // 카테고리 조건이 없는 경우 기본적으로 모든 아이템을 선택
: categories.stream()
.map(category.lastName::eq) // categoryLastName -> category.lastName.eq(categoryLastName)
.reduce(BooleanExpression::or)
.orElse(null);
List.of(categories.split(","))
로 List<String>
으로 만들었다.if(categories.isEmpty())
를 하면 내 예상과 다르게 item.isNotNull()
에 도달하지 않았다.String categories = "";
String[] splitResult = categories.split(","); // splitResult = {""}{length=1}
List<String> parseType = List.of(splitResult); // parseType = [""]{size=1}
System.out.println(parseType.size()); // 출력: 1
List<String> parseType = categories == null || categories.isBlank()
? Collections.emptyList()
: List.of(categories.split(","));
@GetMapping
@Operation(summary = "검색어로 전체 상품 조회", description = "검색어와 검색유형에 따라 전체 상품을 여러개 조회한다.")
public ResponseEntity<PageResponse<SearchItemResponse>> search(
@RequestParam(name = "page", defaultValue = "0") int page,
@RequestParam(name = "size", defaultValue = "12") int size,
@RequestParam(name = "keyword") String keyword,
@RequestParam(name = "categories") @Schema(example = "탁주/막걸리 또는 과실주/와인") String categories
) {
List<String> parseType = categories == null || categories.isBlank()
? Collections.emptyList()
: List.of(categories.split(","));
PageResponse<SearchItemResponse> pageResponse = PageResponse.of(this.itemService.search(page, size, keyword, parseType));
return ResponseEntity.ok().body(pageResponse);
}
@RequiredArgsConstructor
public class ItemRepositoryImpl implements ItemRepositoryCustom {
private final JPAQueryFactory jpaQueryFactory;
@Override
public Page<Item> search(List<String> categories, String keyword, Pageable pageable) {
// 카테고리 검색 조건 생성
BooleanExpression categoryPredicate = categories.isEmpty()
? item.isNotNull() // 카테고리 조건이 없는 경우 기본적으로 모든 아이템을 선택
: categories.stream()
.map(category.lastName::eq) // categoryLastName -> category.lastName.eq(categoryLastName)
.reduce(BooleanExpression::or)
.orElse(null);
// 키워드 검색 조건 생성 - keyword가 없는 경우 카테고리로만 검색
BooleanExpression searchPredicate = keyword.isBlank()
? categoryPredicate
: categoryPredicate.and(item.name.contains(keyword))
.or(categoryPredicate.and(product.name.contains(keyword)))
.or(categoryPredicate.and(maker.name.contains(keyword)));
List<Item> items = jpaQueryFactory
.select(item)
.from(item)
.leftJoin(itemProduct).on(item.eq(itemProduct.item))
.leftJoin(product).on(itemProduct.product.eq(product))
.leftJoin(maker).on(product.maker.eq(maker))
.leftJoin(category).on(item.category.eq(category))
.where(searchPredicate)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
JPAQuery<Long> total = jpaQueryFactory
.select(item.count())
.from(item)
.leftJoin(itemProduct).on(item.eq(itemProduct.item))
.leftJoin(product).on(itemProduct.product.eq(product))
.leftJoin(maker).on(product.maker.eq(maker))
.leftJoin(category).on(item.category.eq(category))
.where(searchPredicate);
return PageableExecutionUtils.getPage(items, pageable, total::fetchOne);
}
}