Product의 Formula Query삭제
- 리뷰 참여자수, 별점 평균은 단일 상품에 대한 정보를 보여줄때만 필요한데 전체 상품 리스트를 가져올 때에도 Formula Query가 실행되기 때문에 List를 가져오는 Server의 동작이 매우 느려진다.
- Formula를 제거하고 단일 상품 요청에 대해서만 리뷰 참여자 수 와, 별점 평균을 따로 계산하도록 수정하였다.
N+1 , Pageable문제
- 기존 Query를 4개로 나누어 해결하였는데 어차피 상품 리스트를 요청하는 경우 Thumbnail을 제외한 나머지 Collection 정보는 필요가 없다.
- batch size를 늘리고 join을 사용해 다음과 같이 변경하였다.
1
2
3
4
5
6
7
8
9
10
11
@Query("SELECT p FROM Product p JOIN ProductImage pi ON p = pi.product WHERE p.type in :category")
Page<Product> getProductPageWithCategory(@Param("category") List<Category> childCategoryList, Pageable pageable);
@Query("SELECT p FROM Product p JOIN ProductImage pi ON p = pi.product WHERE p.company.id = :companyId")
Page<Product> getProductPageWithCompanyId(@Param("companyId") Long companyId, Pageable pageable);
@Query("SELECT p FROM Product p JOIN ProductImage pi ON p = pi.product WHERE p.title LIKE %:keyword% AND p.rocketShipping = true")
Page<Product> getProductPageBySearchWithRocket(@Param("keyword") String keyword, Pageable pageable);
@Query("SELECT p FROM Product p JOIN ProductImage pi ON p = pi.product WHERE p.title LIKE %:keyword%")
Page<Product> getProductPageBySearch(String keyword, Pageable pageable);
- 일반 JOIN을 사용한 경우 ProductImage의 경우 영속화가 되지않아 추가 쿼리가 발생하지만 batch size를 늘렸기 때문에 한번에 가져온 뒤 in절을 통해 추가적인 쿼리가 발생하지 않게된다.
- 이렇게 변경함으로써 ProductService의 많은 코드가 사라질 수 있있고, 직접 Total을 계산하지 않아도 되어 ProductRepository의 각 조건별로 Count하는 Method를 제거할 수 있었다.
상품 구매
- 상품 페이지에서 상품 구매
- option, size, color, count를 전달받아 Order과 OrderDetails Entity를 Create하도록 하였다.
- 장바구니에서 상품 구매
- 장바구니 상품 구매요청의 경우 Cart에서 요청한 User의 Cart중 현재 선택이 되어있는 정보를 토대로 Order과 OrderDetails entity를 Create하도록 하였다.