Category, Company
- 같은 카테고리의 상품 혹은 같은 판매자의 상품 리스트를 볼 수 있어야한다.
Category의 경우 다음과 같은 계층 구조를 사용하였다.
1 2 3 4 5 6 7 8 9 10 11 12 13
public class Category { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id") @OnDelete(action = OnDeleteAction.CASCADE) private Category parent; private String name; }
- 카테고리 요청의 경우 요청이 들어온 카테고리 id에 연결된 모든 Leaf의 Category상품을 전달해야한다. 따라서 Category로 상품 list요청이 들어올 때 Queue를 사용해 해당 Id를 ParentId로 가지는 모든 Category를 반복해서 Queue에 넣고 만약 해당 Id를 ParentId로 사용하는 Category가 없을 경우 Leaf로 판단한다.
- 해당 부분에서 반복이 많이 들어간다고 생각할 수 있지만 Category의 depth가 깊지 않아 문제가 되지 않을것이라 판단된다.
Product Dto
- 상품의경우 검색, 카테고리, 홈페이지에서 보여주는 전체 상품 리스트와 각 상품을 클릭했을때 단일 상품 정보를 보여주는 2가지 경우로 나눌 수 있다.
- 리스트를 보여줄 때 상품의 옵션, 회사, 상세이미지 등의 정보는 필요 없기 때문에 ProductDto, ProductDetailsDto로 나누었다.
단일 상품요청의 경우 해당 상품의 Review에 참여한 사람 수, 별점 평균 정보가 필요하다.
1 2 3
@Formula("(SELECT COUNT(1) FROM Review WHERE Review.product.id = id)") @Formula("(SELECT AVG(starRate) FROM Review WHERE Review.product.id = id)")
위의 두가지 Formula subQeury를 사용해 Review참여자수, 별점 평균을 계산하도록 하였다.
Search
- 검색의 경우 like 쿼리를 사용해 keyword가 product의 title에 포함되는지를 판단해 반환하도록 하였다.
- filter기능의 경우 Pageable을 통해 쉽게 처리할 수 있었다.
장바구니
- 장바구니 담기 기능의 경우 count와 option 값을 받아 단순히 cart entity를 생성하도록 하였다.