이번에는 구매자의 기능을 구현해보려고 한다
장바구니 ( Cart ) 를 구현해 보려고 한다. 초기 설계를 다시보겠다.

장바구니를 구현하기 위해서 다음을 고려하였다.
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Entity
public class Cart {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private int count; // 카트에 담긴 상품 개수
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="user_id")
User user;
@OneToMany(fetch = FetchType.EAGER)
private List<Cart_item> cart_items = new ArrayList<>();
@DateTimeFormat(pattern = "yyyy-mm-dd")
private LocalDate createDate; // 날짜
@PrePersist
public void createDate(){
this.createDate = LocalDate.now();
}
public static Cart createCart(User user){
Cart cart = new Cart();
cart.user = user;
cart.count = 0;
return cart;
}
@Repository
public interface CartRepository extends JpaRepository<Cart,Integer> {
Cart findByUserId(int userId);
}
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Entity
public class Cart_item {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="cart_id")
private Cart cart;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name="item_id")
private Item item;
private int count; // 카트에 담긴 상품 개수
@DateTimeFormat(pattern = "yyyy-mm-dd")
private LocalDate createDate; // 날짜
@PrePersist // DB에 INSERT 되기 직전에 실행. 즉 DB에 값을 넣으면 자동으로 실행됨
public void createDate() {
this.createDate = LocalDate.now();
}
public static Cart_item createCartItem(Cart cart,Item item,int count){
Cart_item cartItem = new Cart_item();
cartItem.setCart(cart);
cartItem.setItem(item);
cartItem.setCount(count);
return cartItem;
}
public void addCount(int count){
this.count += count;
}
}
public interface Cart_itemRepository extends JpaRepository<Cart_item,Integer> {
Cart_item findByCartIdAndItemId(int cartId, long itemId);
}
장바구니의 수행기능은 다음과 같다
User에게 장바구니 생성
장바구니에 Item 추가하기
장바구니 조회하기
장바구니 Item 삭제하기
장바구니 결제하기
public void createCart(User user){
Cart cart = Cart.createCart(user);
cartRepository.save(cart);
}
@Transactional
public void addCart(User user, Item item, int count){
Cart cart = cartRepository.findByUserId(user.getId());
// cart 가 비어있다면 생성.
if(cart == null){
cart = Cart.createCart(user);
cartRepository.save(cart);
}
// cart_item 생성
Cart_item cart_item = cart_itemRepository.findByCartIdAndItemId(cart.getId(),item.getId());
// cart_item이 비어있다면 새로 생성.
if(cart_item == null){
cart_item = Cart_item.createCartItem(cart,item,count);
cart_itemRepository.save(cart_item);
cart.setCount(cart.getCount() + 1);
}else{
// 비어있지 않다면 그만큼 갯수를 추가.
cart_item.addCount(count);
}
}
public List<Cart_item> userCartView(Cart cart){
List<Cart_item> cart_items = cart_itemRepository.findAll();
List<Cart_item> user_items = new ArrayList<>();
for(Cart_item cart_item : cart_items){
if(cart_item.getCart().getId() == cart.getId()){
user_items.add(cart_item);
}
}
return user_items;
}
public void cartItemDelete(int id){
cart_itemRepository.deleteById(id);
}
public void cartDelete(int id){
List<Cart_item> cart_items = cart_itemRepository.findAll(); // 전체 cart_item 찾기
// 반복문을 이용하여 접속 User의 Cart_item 만 찾아서 삭제
for(Cart_item cart_item : cart_items){
if(cart_item.getCart().getUser().getId() == id){
cart_item.getCart().setCount(cart_item.getCart().getCount() - 1);
cart_itemRepository.deleteById(cart_item.getId());
}
}
}
@Transactional
public void cartPayment(int id){
List<Cart_item> cart_items = cart_itemRepository.findAll(); // 전체 cart_item 찾기
List<Cart_item> userCart_items = new ArrayList<>();
User buyer = userRepository.findById(id).get();
// 반복문을 이용하여 접속 User의 Cart_item만 찾아서 저장
for(Cart_item cart_item : cart_items){
if(cart_item.getCart().getUser().getId() == buyer.getId()){
userCart_items.add(cart_item);
}
}
// 반복문을 이용하여 접속 User의 Cart_item 만 찾아서 삭제
for(Cart_item cart_item : userCart_items){
// 재고 변경
int stock = cart_item.getItem().getStock(); // 현재 재고를 변수에 저장
stock = stock - cart_item.getCount(); // 저장된 변수를 결제한 갯수만큼 빼준다
cart_item.getItem().setStock(stock); // 재고갯수 변경
// 금액 처리
User seller = cart_item.getItem().getUser();
int cash = cart_item.getItem().getPrice(); // 아이템 가격을 변수에 저장
buyer.setMoney(cash * -1);
seller.setMoney(cash);
}
}
Cart 또한 User의 기능중 하나이므로 UserPageController.java에 추가하여 구현하도록 하였다.
Service에서 설계한 기능인 5가지 기능을 View 단계에서 처리하도록한다.
@GetMapping("/user/{id}/cart")
public String myCartPage(@PathVariable("id") Integer id,Model model,@AuthenticationPrincipal PrincipalDetails principalDetails){
// 로그인 User == 접속 User
if(principalDetails.getUser().getId() == id){
// User의 장바구니를 가져온다.
Cart cart = principalDetails.getUser().getCart();
// 장바구니의 아이템을 가져온다.
List<Cart_item> cart_items = cartService.userCartView(cart);
int totalPrice = 0;
for(Cart_item cart_item : cart_items){
totalPrice += ( cart_item.getItem().getPrice() * cart_item.getCount());
}
model.addAttribute("cart_itemList",cart_items);
model.addAttribute("totalPrice",totalPrice);
model.addAttribute("user",userPageService.findUser(id));
return "/cart/cart";
}else{
return "redirect:/main";
}
}
@PostMapping("/user/{id}/cart/{itemId}")
public String myCartAdd(@PathVariable("id") Integer id,@PathVariable("itemId") Long itemId,int count){
User user = userPageService.findUser(id);
Item item = itemService.itemView(itemId);
cartService.addCart(user,item,count);
return "redirect:/item/view/{itemId}";
}
@GetMapping("/user/{id}/cart/{cart_itemId}/delete")
public String myCartDelete(@PathVariable("id") Integer id, @PathVariable("cart_itemId") int cart_itemId, @AuthenticationPrincipal PrincipalDetails principalDetails){
User user = userPageService.findUser(id);
user.getCart().setCount(user.getCart().getCount() - 1);
cartService.cartItemDelete(cart_itemId);
return "redirect:/user/{id}/cart";
}
@PostMapping("/user/{id}/cart/checkout")
public String myCartPayment(@PathVariable("id") Integer id, Model model){
User user = userPageService.findUser(id);
cartService.cartPayment(id); // 결제처리
cartService.cartDelete(id); // 장바구니 비우기
return "redirect:/main";
}
장바구니를 구현하면서 가장 어려웠던 점은
OneToOne, OneToMany, ManyToOne 맵핑을 하는것을 자세하게 모르는 점이었다. 이러한 점은 나중에 따로 공부하여 블로그에 올리도록 하려한다.
내가 쇼핑몰에서 사용하던 장바구니를 의외로 손쉽게 구현 할 수 있는것 같았다.
물론 FrontEnd단에서 장바구니 화면을 구현하는것이 어려웠지만 부트스트랩을 이용하여 할 수 있었다.
다음에는 장바구니를 통해 구매하기를 누르면 주문이 들어가는것을 구현하려한다.
저 혹시 jsp도 알 수 있을까요?