장바구니 조회

루민 ·2023년 5월 2일
0

📝Server

cartQueryDto

@Getter
@Setter
public class CartQueryDto {

    private Long cartItemId;
    private String itemName;  //상품명
    private int count;  //수량
    private int price; //상품 가격

    public CartQueryDto(Long cartItemId, String itemName, int count, int price) {
        this.cartItemId = cartItemId;
        this.itemName = itemName;
        this.count = count;
        this.price = price;
    }
}
  • CartQueryDto 클래스는 장바구니 조회에 쓰일 DTO입니다.

CartQueryRepository

@Repository
@RequiredArgsConstructor
public class CartQueryRepository {

    private final EntityManager em;

     public List<CartQueryDto> findCartQueryDtos(Long cartId) {
        List<CartQueryDto> cartQueryDtoList = em.createQuery(
                        "select new com.toyproject.ecommerce.repository.query.CartQueryDto(ci.id, i.name, ci.count, i.price, im.storeName)" +
                                " from CartItem ci" +
                                " join ci.item i" +
                                " join i.itemImageList im" +
                                " where ci.cart.id = :cartId and" +
                                " im.firstImage='Y'", CartQueryDto.class)
                .setParameter("cartId", cartId)
                .getResultList();

        return cartQueryDtoList;
    }
}
  • 각 사용자의 장바구니 목록을 조회하는 Repository입니다.
  • DTO를 직접 조회하는 방식을 선택하였습니다.
  • DTO를 직접 조회하는 방식은 말 그대로 엔티티를 조회하는 것이 아닌 DB를 조회해서 DTO의 필드에 값을 채워주는 방식입니다.
  • 따라서 데이터를 선택적으로 조회 가능하다는 장점이 있습니다.
  • DTO를 직접 조회하는 방식은 엔티티 조회가 아니기 때문에 영속성 컨텍스트에 데이터가 들어가지 않습니다!!
  • 묵시적 조인 조심하기!!
  • 상품 이미지를 출력하기 위해 itemImage 테이블에 firstImage 필드(대표 이미지 추가 여부)를 추가했습니다.

CartQueryRepository를 따로 만든 이유

  • CartItemRepository에 쿼리를 작성하지 않고 CartQueryRepository를 따로 만들고 쿼리를 작성하였습니다.
  • CartItemRepository는 cartItem 엔티티를 조회하는 용도(핵심 비지니스)로만 사용하고 엔티티가 아닌 특정 화면을 조회하는 쿼리(장바구니 조회하는 쿼리 등), API 쿼리는 CartQueryRepository로 따로 작성하였습니다.
  • 관심사의 분리 -> 단일 책임 원칙(SRP, Single Reponsibility Principle)

CartService

 	@Transactional(readOnly = true)
    public List<CartQueryDto> findCartItems(Long memberId) {
        Cart cart = cartRepository.findByMemberId(memberId).orElseThrow(EntityNotFoundException::new);  // () -> new EntityNotFoundException()
        List<CartQueryDto> cartQueryDtos = cartQueryRepository.findCartQueryDtos(cart.getId());
        return cartQueryDtos;
    }
  • 회원의 장바구니 상품을 조회하는 서비스 로직입니다.

CartController

 	@GetMapping("/cart")
    public String cartView(Model model, HttpServletRequest request) {

        Member member = getMember(request);

        List<CartQueryDto> cartItemListForm = cartService.findCartItems(member.getId());
        model.addAttribute("cartItemListForm", cartItemListForm);

        return "cart/cartView";
    }
    
    private Member getMember(HttpServletRequest request) {

        HttpSession session = request.getSession(false);

        //비로그인 사용자
        if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) {
            return null;
        }

        //세션에 저장되어있는 회원정보 가져오기
        Member member = (Member) session.getAttribute(SessionConst.LOGIN_MEMBER);
        return member;
    }
  • 세션을 조회해서 현재 세션에 저장되어있는 회원을 찾아서 서비스를 호출합니다.
  • 장바구니 페이지(cartView)로 이동!


📝장바구니 페이지 뷰

  • GitHub
  • 모델을 통해 전달된 장바구니에 담긴 상품정보를 화면에 출력해주는 작업을 진행하였습니다.
  • 체크박스 속성을 설정해주고, Onchange을 이용하여 체크가 된 상품의 개수가 바뀌면 자동으로 계산되는 로직을 구현하였습니다.


참고

체크박스 값 변화 감지 https://www.codingfactory.net/13044
https://carina16.tistory.com/143

다중 체크 값 https://doinge-coding.tistory.com/entry/jquery-check-box-%EB%8B%A4%EC%A4%91-%EC%B2%B4%ED%81%AC%EA%B0%92-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%AC%ED%8A%B8-%EC%B2%B4%ED%81%AC%EB%B0%95%EC%8A%A4-%EC%B2%B4%ED%81%AC%EA%B0%92-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0

0개의 댓글