진짜 개발자
본문 바로가기

FrameWork/Spring JPA

Spring JPA - JPA를 이용해 Commerce App 만들기 - 9.2 (카테고리 기능 기존 시스템과 결합)

728x90
이번에는, 지난 포스팅(httpsgalid1

이번에는, 지난 포스팅(https://galid1.tistory.com/774)에서 구현했던, 무한카테고리 기능을 기존 시스템과 결합하는 방법을 알아보도록 하겠습니다.

 

 

 

1. 기존 시스템과 카테고리 기능 결합

사실 최초 설계시, 카테고리를 염두하고 설계를 했었는데요, 카테고리만을 제외하고 구현을 했었습니다. 나중에 카테고리 기능을 추가하면서, 불편한 점이 없는지를 확인해보고 싶었기 때문이기도 합니다. 기존 설계에 비해서 달라진 점은 빨간 사각형에 해당하는 필드가 추가 되었다는 것 입니다. 왜 인지는 이전 포스팅을 참고해주세요.

 

우선 이전 포스팅에서 무한 카테고리 형태로 카테고리 기능을 구현했습니다.

 

 

구현했던 카테고리 기능을 이제, 기존 시스템에 카테고리 기능을 결합할 것입니다. 

 

 

 

1.1 과정

  1. ItemEntity에 Category를 참조할 수 있는 categoryId 필드를 추가합니다.
  2. 아이템 추가시, 아이템이 속할 카테고리를 같이 지정해 생성합니다.
  3. 카탈로그 화면에서, 아이템을 화면에 보여줄때, 카테고리를 조건에 이용해 쿼리결과를 만듭니다.

 

 

 

1.2 1:N이 아닌 N:1로 표현하는 이유

기본적으로 카테고리와 아이템의 연관관계를 생각해보면, 카테고리에 여러 상품들이 속하는 형태이므로, Category, Item의 연관관계를 1 : N으로 생각할 수 있습니다. 하지만, 여러 상황들을 따져보면 N : 1이 보다 효율적히고 적합함을 알 수 있습니다. 아래에서 자세히 알아보겠습니다.

 

새로운 아이템을 추가하는 경우

맨 위에서 보여드린 전체 그림을 보면, 카테고리에서 자신에게 속한 Item들을 Set과 같은 집합 형태로 가지고 있지 않고, Item에서 자신이 속한 CategoryId를 가지고 있는 것을 볼 수 있습니다. 카테고리가 추가되면서, 기존 item들은 카테고리 filed가 모두 null입니다. 따라서 모든 item들에 대해 카테고리id를 추가해주어야 합니다.

 

하지만, 반대로 Category에서 해당 Category에 속한 Item들을 Set형태로 가지고 있는것은 매우 비효율적 입니다. 어차피 카테고리 기능이 추가되면서, 모든 item들을 특정 카테고리에 속하도록 하는 과정은 필요하며, 만약 새로운 카테고리가 추가되는 경우, 기존 item들을 모두 살펴보며, 새로운 카테고리에 속하는지를 확인한 뒤, 해당하는 아이템들을 카테고리에 추가하도록 해야 하기 때문입니다.

 

 

카탈로그 조회하는 경우

1:N의 연관관계로 표현했을때, 카탈로그에서 상품들을 보여주기위해서는 다음과 같이 구현이 가능합니다.

 

이런 경우 카탈로그를 조회할때마다, 카테고리에 속한 모든 Item들을 조회하고, page, size를 이용해 페이징된 데이터를 반환하게 됩니다.

 

하지만, 다시 생각해보면, 사용자가 카탈로그에 접근할때에는, 모든 카테고리에 속한 아이템목록이 필요하지 않습니다. 현재 사용자가 볼 페이지에 포함된 수만큼의 아이템만이 필요하기 때문입니다. 만약 Category에 속한 아이템이 수만 수십만개라면, 엄청난 성능저하가 일어날 것 입니다.

 

반면, N:1로 연관관계를 표현한 경우, Item의 입장에서 특정 categoryId에 해당하는 Item들만을 조회해 올 수 있기 때문에 성능 최적화를 할 수 있습니다.

 

 

 

 

2. 기존 시스템과 결합

2.1 ItemEntity 수정

우선 CategoryId 연관을 표현하기 위한 CategoryId 필드를 추가 합니다.

 

 

registerItemForm.html

Item 등록 form에 categoryId를 입력받는 칸을 추가합니다.

 

 

 

2.2 DB 수정

기존에 등록되어 있던 Item들에는 Category_id 필드가 존재하지 않았기 때문에 해당 필드가 NULL로 되어 있을 것입니다. 저는 이전 포스팅에서 등록했던 Category들중 적절한 Category를 찾아 기입해주었습니다.

 

 

 

2.3 Catalog 조회 로직 수정

ItemSearchForm 필드 수정

Catalog 조회시 CategoryId 조건을 추가하기 위해서, ItemSearchForm에 categoryId 필드를 추가합니다.

 

 

CatalogDao 조회 조건 수정

CatalogDao의 query where절에 categoryId 조건을 추가합니다.

 

 

 

 

 

3. Category 화면 구현

위의 그림에서 카테고리에 해당하는 부분은 별도로 fragment로 직접 구현을 했습니다. 필요하신 분은 다음 링크를 통해 확인해주세요 https://gitlab.com/galid1/jpa-commerce/-/blob/master/src/main/resources/templates/fragments/category.html

 

 

3.1 Controller 수정

우선, CatalogController의 Handler에 Category를 Parameter로 전달받기 위한 필드를 추가했습니다.

 

예를들어, catalog에 접근하는 사용자는 위와 같이 요청을 보낼것입니다. 중요한 점은 @RequestParam의 required 속성을 false로 지정해주어야 한다는 것 입니다. 맨 처음 카탈로그에 접근하는 사용자는 아직 Category를 선택하지 않은 상태일 수 있기 때문입니다.

 

 

 

3.2 category 화면 수정

Category.html을 열어 <a> 태그에서 지정된 url을 구축하신 handler에 맞추어 변경을 해주어야 합니다.

 

 

 

3.3 catalog 화면 수정

앞서 알려드린 주소를 통해 category 페이지를 완성 하셨다면, Catalog 화면에 해당 fragment를 추가해주면 끝입니다.