8w8u8

판매제품을 direct하게 연결하면 안될까? 본문

back-end

판매제품을 direct하게 연결하면 안될까?

jud1th 2025. 7. 5. 18:56

본격적인 여름프로젝트(SWS)를 진행하기에 앞서, 동아리에서 간단한 프로젝트를 진행하고 있다.

알라딘 중고제품 웹사이트 클론코딩

개요

  • 디자인팀이 현재 알라딘 사이트를 리디자인
  • 상품(product)에 대해 여러 중고제품(item)이 존재하는 구조
    ex) "어린왕자"라는 책에 대해 여러 권의 판매하는 중고제품이 존재할 수 있다. 이 중고제품들은 상태, 지점 위치 등이 다르다.
  • 간소화한 부분들이 존재
    1. 모든 카테고리들을 활성화x - '건강취미'만 접속 가능
    2. 모든 지점들을 활성화x - '전체보기', '신촌점만 보기'
    3. 자체 로그인x, 카카오 로그인만 가능
    4. 제품등록 기능 구현x
    5. 주문 및 결제 기능 구현x
      • 즉, 있어야 하는 기능들은 다음과 같다:
      1. 카카오 로그인을 통한 회원가입, 로그아웃
      2. 리뷰 생성, 한 상품에 대한 리뷰 전체조회, 리뷰 삭제
      3. 장바구니에 제품 추가, 장바구니 제품 전체 조회, 장바구니 단일 제품 삭제
      4. 상품 전체 조회, 상품 검색, 상품 상세 조회, 상품타입별(서적/음반/굿즈) 조회
      5. 신촌점 메인페이지에서 보여질 제품들 조회(상품타입별 4개씩)
      6. 상품상세조회페이지에서 보일 제품 목록 조회

ERD

작성한 ERD는 다음과 같다.

장바구니와 판매제품을 direct하게 연결하면 안될까?

JPA에서는 다대다 관계를 표현하기 위해 @ManyToMany 를 지원한다.
그러나, 실무에서는 다음과 같은 이유로 사용하지 않는다.

  • 관계형 데이터베이스는 정규화된 테이블 2개로 다대다 관계를 표현할 수 없다.
  • @ManyToMany를 사용하면 JPA가 자동으로 중간 테이블을 생성해주긴 하지만, 복잡한 조인 쿼리를 발생시켜 개발자가 의도하지 않은 방식으로 작동할 수 있다.
  • @ManyToMany를 사용하면 중간 테이블에 추가 컬럼이 필요한 경우, 추가 데이터를 배핑하지 못한다.

다대다 관계는 일대다, 다대일 관계로 풀어 사용하자!

연결 테이블 엔티티를 추가하는 셈이다.
ERD에서 Item과 Cart 사이에 CartItem을 넣어준 것을 확인할 수 있다.

  • Item
    public class Item {    
    ...            
      @OneToMany(mappedBy = "item", cascade = CascadeType.ALL, orphanRemoval = true)
      @Builder.Default
      private List<CartItem> cartItems = new ArrayList<>();
    ...  
    

- Cart
``` java
public class Cart {    
...            
    @OneToMany(mappedBy = "cart", cascade = CascadeType.ALL, orphanRemoval = true)
    @Builder.Default
    private List<CartItem> cartItems = new ArrayList<>();
...  
  • CartItem

    @Entity
    public class CartItem {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      @Column(name = "cart_item_id", updatable = false)
      private Long cartItemId;
    
      // FK
      @ManyToOne(fetch = FetchType.LAZY)
      @JoinColumn(name = "cart_id", updatable = false)
      private Cart cart;
    
      // FK
      @ManyToOne(fetch = FetchType.LAZY)
      @JoinColumn(name = "item_id", updatable = false)
      private Item item;
    }
    

```