Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: 상품 정렬 로직에 불필요한 과정 제거 #4

Merged
merged 1 commit into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,4 @@ public static ItemSortType from(String sortType) {
.findAny()
.orElseThrow(() -> new NotFoundItemSortTypeException("요청하신 정렬기준은 존재하지 않습니다."));
}

public boolean isPopular() {
return this == POPULAR;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.net.URI;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -40,15 +41,13 @@ public class ItemController {

@GetMapping
public ResponseEntity<FindItemsResponse> findItemsByCategory(
@RequestParam(defaultValue = DEFAULT_PREVIOUS_ID) Long lastItemId,
@RequestParam(defaultValue = DEFAULT_PREVIOUS_ID) Long lastIdx,
@RequestParam int size,
Pageable pageable,
@RequestParam String main,
@RequestParam(required = false) String sub,
@RequestParam String sort) {

FindItemsByCategoryCommand findItemsByCategoryCommand = FindItemsByCategoryCommand.of(
lastItemId, lastIdx, main, sub, size, sort);
pageable.getPageNumber(), pageable.getPageSize(), main, sub, sort);
FindItemsResponse findItemsResponse = itemService.findItemsByCategory(
findItemsByCategoryCommand);
return ResponseEntity.ok(findItemsResponse);
Expand All @@ -61,14 +60,9 @@ public ResponseEntity<FindItemDetailResponse> findItemDetail(@PathVariable Long
}

@GetMapping("/new")
public ResponseEntity<FindItemsResponse> findNewItems(
@RequestParam(defaultValue = DEFAULT_PREVIOUS_ID) Long lastIdx,
@RequestParam(defaultValue = DEFAULT_PREVIOUS_ID) Long lastItemId,
@RequestParam int size,
@RequestParam(defaultValue = "POPULAR") String sort
) {
FindNewItemsCommand findNewItemsCommand = FindNewItemsCommand.of(lastIdx, lastItemId, size,
sort);
public ResponseEntity<FindItemsResponse> findNewItems(Pageable pageable) {
FindNewItemsCommand findNewItemsCommand = FindNewItemsCommand.of(pageable.getPageNumber(),
pageable.getPageSize());
return ResponseEntity.ok(itemService.findNewItems(findNewItemsCommand));
}

Expand All @@ -80,14 +74,9 @@ public ResponseEntity<FindNewItemsResponse> findNewItemsWithRedis(
}

@GetMapping("/hot")
public ResponseEntity<FindItemsResponse> findHotItems(
@RequestParam(defaultValue = DEFAULT_PREVIOUS_ID) Long lastIdx,
@RequestParam(defaultValue = DEFAULT_PREVIOUS_ID) Long lastItemId,
@RequestParam int size,
@RequestParam(defaultValue = "POPULAR") String sort
) {
FindHotItemsCommand findHotItemsCommand = FindHotItemsCommand.of(lastIdx, lastItemId, size,
sort);
public ResponseEntity<FindItemsResponse> findHotItems(Pageable pageable) {
FindHotItemsCommand findHotItemsCommand = FindHotItemsCommand.of(pageable.getPageSize(),
pageable.getPageSize());
return ResponseEntity.ok(itemService.findHotItems(findHotItemsCommand));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@

public interface ItemRepositoryCustom {

List<Item> findNewItemsOrderBy(Long lastIdx, Long lastItemId, ItemSortType sortType,
Pageable pageable);
List<Item> findNewItemsOrderBy(Pageable pageable);

List<Item> findHotItemsOrderBy(Long lastIdx, Long lastItemId, ItemSortType sortType,
Pageable pageable);
List<Item> findHotItemsOrderBy(Pageable pageable);

List<Item> findByMainCategoryOrderBy(MainCategory mainCategory, Long lastIdx, Long lastItemId,
ItemSortType sortType, Pageable pageable);
List<Item> findByMainCategoryOrderBy(MainCategory mainCategory, ItemSortType sortType,
Pageable pageable);

List<Item> findBySubCategoryOrderBy(MainCategory mainCategory, SubCategory subCategory,
Long lastIdx, Long lastItemId, ItemSortType sortType, Pageable pageable);
ItemSortType sortType, Pageable pageable);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.prgrms.nabmart.domain.item.repository;

import static com.prgrms.nabmart.domain.item.QItem.item;
import static com.prgrms.nabmart.domain.order.QOrderItem.orderItem;
import static com.prgrms.nabmart.domain.statistics.QStatistics.statistics;

import com.prgrms.nabmart.domain.category.MainCategory;
Expand All @@ -11,11 +10,8 @@
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
Expand All @@ -31,98 +27,61 @@ public class ItemRepositoryImpl implements ItemRepositoryCustom {
private static final int HOT_PRODUCT_REFERENCE_ORDERS = 10;

@Override
public List<Item> findNewItemsOrderBy(Long lastIdx, Long lastItemId, ItemSortType sortType,
Pageable pageable) {
OrderSpecifier orderSpecifier = createOrderSpecifier(sortType);
public List<Item> findNewItemsOrderBy(Pageable pageable) {
Predicate predicate = item.createdAt.after(
LocalDateTime.now().minus(NEW_PRODUCT_REFERENCE_TIME, ChronoUnit.WEEKS));
LocalDateTime.now().minusWeeks(NEW_PRODUCT_REFERENCE_TIME));

return queryFactory
.selectFrom(item)
.join(item.statistics, statistics)
.where(predicate)
.groupBy(item)
.having(
getCondition(lastIdx, lastItemId, sortType)
)
.orderBy(orderSpecifier, item.itemId.asc())
.orderBy(item.createdAt.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
}

@Override
public List<Item> findHotItemsOrderBy(Long lastIdx, Long lastItemId, ItemSortType sortType,
Pageable pageable) {
OrderSpecifier orderSpecifier = createOrderSpecifier(sortType);
Predicate predicate = item.rate.gt(HOT_PRODUCT_REFERENCE_RATE);
Predicate orderCondition = JPAExpressions.select(orderItem.quantity.sum().coalesce(0))
.from(orderItem)
.where(orderItem.itemId.eq(item.itemId))
.gt(HOT_PRODUCT_REFERENCE_ORDERS);
public List<Item> findHotItemsOrderBy(Pageable pageable) {

return queryFactory
.selectFrom(item)
.join(item.statistics, statistics)
.where(predicate, getCondition(lastIdx, lastItemId, sortType))
.groupBy(item)
.having(
getCondition(lastIdx, lastItemId, sortType),
orderCondition
)
.orderBy(orderSpecifier, item.itemId.asc())
.where(item.rate.gt(HOT_PRODUCT_REFERENCE_RATE)
.and(item.statistics.orders.gt(HOT_PRODUCT_REFERENCE_ORDERS)))
.orderBy(item.statistics.orders.desc(), item.itemId.asc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
}

@Override
public List<Item> findByMainCategoryOrderBy(MainCategory mainCategory, Long lastIdx,
Long lastItemId, ItemSortType sortType, Pageable pageable) {

Predicate mainCategoryCondition = item.mainCategory.eq(mainCategory);
OrderSpecifier orderSpecifier = createOrderSpecifier(sortType);
public List<Item> findByMainCategoryOrderBy(MainCategory mainCategory, ItemSortType sortType,
Pageable pageable) {

return queryFactory.selectFrom(item)
.where(mainCategoryCondition, getCondition(lastIdx, lastItemId, sortType))
.orderBy(orderSpecifier, item.itemId.desc())
.where(item.mainCategory.eq(mainCategory))
.orderBy(createOrderSpecifier(sortType), item.itemId.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
}

@Override
public List<Item> findBySubCategoryOrderBy(MainCategory mainCategory, SubCategory subCategory,
Long lastIdx, Long lastItemId, ItemSortType sortType, Pageable pageable) {

Predicate mainCategoryCondition = item.mainCategory.eq(mainCategory);
Predicate subCategoryCondition = item.subCategory.eq(subCategory);
OrderSpecifier orderSpecifier = createOrderSpecifier(sortType);
ItemSortType sortType, Pageable pageable) {

return queryFactory.selectFrom(item)
.where(mainCategoryCondition, subCategoryCondition,
getCondition(lastIdx, lastItemId, sortType))
.orderBy(orderSpecifier, item.itemId.desc())
.where(item.mainCategory.eq(mainCategory), item.subCategory.eq(subCategory))
.orderBy(createOrderSpecifier(sortType), item.itemId.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
}

private Predicate getCondition(Long lastIdx, Long lastItemId, ItemSortType sortType) {
return switch (sortType) {
case NEW -> item.itemId.lt(lastIdx);
case HIGHEST_AMOUNT -> item.price.lt(lastIdx)
.or(item.price.eq(lastIdx.intValue()).and(item.itemId.lt(lastItemId)));
case LOWEST_AMOUNT -> item.price.gt(lastIdx)
.or(item.price.eq(lastIdx.intValue()).and(item.itemId.lt(lastItemId)));
case DISCOUNT -> item.discount.lt(lastIdx)
.or(item.discount.eq(lastIdx.intValue()).and(item.itemId.lt(lastItemId)));
default -> item.statistics.orders.lt(lastIdx);
};
}

private OrderSpecifier createOrderSpecifier(ItemSortType sortType) {

return switch (sortType) {
case NEW -> new OrderSpecifier<>(Order.DESC, item.itemId);
case NEW -> new OrderSpecifier<>(Order.DESC, item.createdAt);
case HIGHEST_AMOUNT -> new OrderSpecifier<>(Order.DESC, item.price);
case LOWEST_AMOUNT -> new OrderSpecifier<>(Order.ASC, item.price);
case DISCOUNT -> new OrderSpecifier<>(Order.DESC, item.discount);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import com.prgrms.nabmart.domain.item.service.response.FindNewItemsResponse;
import com.prgrms.nabmart.domain.item.service.response.FindNewItemsResponse.FindNewItemResponse;
import com.prgrms.nabmart.domain.item.service.response.ItemRedisDto;
import com.prgrms.nabmart.domain.order.repository.OrderItemRepository;
import com.prgrms.nabmart.domain.review.service.RedisCacheService;
import java.util.ArrayList;
import java.util.Comparator;
Expand Down Expand Up @@ -103,9 +102,7 @@ public FindItemDetailResponse findItemDetail(FindItemDetailCommand findItemDetai
@Transactional(readOnly = true)
public FindItemsResponse findNewItems(FindNewItemsCommand findNewItemsCommand) {
return FindItemsResponse.from(
itemRepository.findNewItemsOrderBy(findNewItemsCommand.lastIdx(),
findNewItemsCommand.lastItemId(), findNewItemsCommand.sortType(),
findNewItemsCommand.pageRequest()));
itemRepository.findNewItemsOrderBy(findNewItemsCommand.pageRequest()));
}

@Transactional(readOnly = true)
Expand Down Expand Up @@ -176,23 +173,18 @@ private MainCategory getMainCategoryById(Long mainCategoryId) {
private List<Item> findItemsByMainCategoryFrom(
FindItemsByCategoryCommand findItemsByCategoryCommand) {

Long lastItemId = findItemsByCategoryCommand.lastItemId();
Long lastIdx = findItemsByCategoryCommand.lastIdx();
ItemSortType itemSortType = findItemsByCategoryCommand.itemSortType();
PageRequest pageRequest = findItemsByCategoryCommand.pageRequest();
String mainCategoryName = findItemsByCategoryCommand.mainCategoryName().toLowerCase();
MainCategory mainCategory = mainCategoryRepository.findByName(mainCategoryName)
.orElseThrow(() -> new NotFoundCategoryException("없는 대카테고리입니다."));

return itemRepository.findByMainCategoryOrderBy(mainCategory, lastIdx, lastItemId,
itemSortType, pageRequest);
return itemRepository.findByMainCategoryOrderBy(mainCategory, itemSortType, pageRequest);
}

private List<Item> findItemsBySubCategoryFrom(
FindItemsByCategoryCommand findItemsByCategoryCommand) {

Long lastItemId = findItemsByCategoryCommand.lastItemId();
Long lastIdx = findItemsByCategoryCommand.lastIdx();
ItemSortType itemSortType = findItemsByCategoryCommand.itemSortType();
PageRequest pageRequest = findItemsByCategoryCommand.pageRequest();
String mainCategoryName = findItemsByCategoryCommand.mainCategoryName().toLowerCase();
Expand All @@ -202,15 +194,13 @@ private List<Item> findItemsBySubCategoryFrom(
SubCategory subCategory = subCategoryRepository.findByName(subCategoryName)
.orElseThrow(() -> new NotFoundCategoryException("없는 소카테고리입니다."));

return itemRepository.findBySubCategoryOrderBy(mainCategory, subCategory, lastIdx,
lastItemId, itemSortType, pageRequest);
return itemRepository.findBySubCategoryOrderBy(mainCategory, subCategory, itemSortType,
pageRequest);
}

@Transactional(readOnly = true)
public FindItemsResponse findHotItems(FindHotItemsCommand findHotItemsCommand) {
List<Item> items = itemRepository.findHotItemsOrderBy(findHotItemsCommand.lastIdx(),
findHotItemsCommand.lastItemId(), findHotItemsCommand.sortType(),
findHotItemsCommand.pageRequest());
List<Item> items = itemRepository.findHotItemsOrderBy(findHotItemsCommand.pageRequest());
return FindItemsResponse.from(items);
}
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,11 @@
package com.prgrms.nabmart.domain.item.service.request;

import com.prgrms.nabmart.domain.item.ItemSortType;
import java.util.Objects;
import org.springframework.data.domain.PageRequest;

public record FindHotItemsCommand(
Long lastIdx,
Long lastItemId,
PageRequest pageRequest,
ItemSortType sortType
) {
public record FindHotItemsCommand(PageRequest pageRequest) {

private static final int DEFAULT_PAGE_NUMBER = 0;

public static FindHotItemsCommand of(Long lastIdx, Long lastItemId, int pageSize,
String sortType) {
if (isFirstIdx(lastIdx)) {
lastIdx = Long.parseLong(String.valueOf(Integer.MAX_VALUE));
if (Objects.equals(sortType, "LOWEST_AMOUNT") || Objects.equals(sortType, "NEW")) {
lastIdx = Long.MIN_VALUE;
}
}

ItemSortType itemSortType = ItemSortType.from(sortType);
PageRequest pageRequest = PageRequest.of(DEFAULT_PAGE_NUMBER, pageSize);
return new FindHotItemsCommand(lastIdx, lastItemId, pageRequest, itemSortType);
}

private static boolean isFirstIdx(Long previousItemId) {
return previousItemId < 0;
public static FindHotItemsCommand of(int page, int size) {
PageRequest pageRequest = PageRequest.of(page, size);
return new FindHotItemsCommand(pageRequest);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,19 @@

@Slf4j
public record FindItemsByCategoryCommand(
Long lastItemId,
Long lastIdx,
String mainCategoryName,
String subCategoryName,
PageRequest pageRequest,
ItemSortType itemSortType) {

private static final int DEFAULT_PAGE_NUMBER = 0;

public static FindItemsByCategoryCommand of(
Long lastItemId, Long lastIdx, String mainCategoryName, String subCategoryName,
int pageSize,
String sortType
public static FindItemsByCategoryCommand of(int page, int size, String mainCategoryName,
String subCategoryName, String sortType
) {

validateMainCategoryName(mainCategoryName);
ItemSortType itemSortType = ItemSortType.from(sortType);
PageRequest pageRequest = PageRequest.of(DEFAULT_PAGE_NUMBER, pageSize);
if (isFirstItemId(lastItemId)) {
lastIdx = redeclareLastIdx(itemSortType);
lastItemId = Long.MAX_VALUE;
}
return new FindItemsByCategoryCommand(lastItemId, lastIdx, mainCategoryName,
subCategoryName,
pageRequest,
PageRequest pageRequest = PageRequest.of(page, size);
return new FindItemsByCategoryCommand(mainCategoryName, subCategoryName, pageRequest,
itemSortType);
}

Expand All @@ -39,12 +28,4 @@ private static void validateMainCategoryName(String mainCategoryName) {
throw new NotFoundCategoryException("카테고리명은 필수 항목입니다.");
}
}

private static boolean isFirstItemId(Long previousItemId) {
return previousItemId < 0;
}

private static long redeclareLastIdx(ItemSortType itemSortType) {
return itemSortType.getDefaultValue();
}
}
Loading
Loading