[Spring] 실전! 스프링 부트와 JPA 활용 # 주문 내역 각 Item 별 분할 출력

김상현·2022년 11월 5일
0

Spring

목록 보기
5/13
post-thumbnail

📒 [실전! 스프링 부트와 JPA 활용 - 김영한] 학습 후 정리자료입니다.
📒 Thymeleaf 공식 홈페이지에서 참고한 내용입니다.


📍 코드 수정이 필요한 부분

  • 기존의 코드는 1개의 주문(Order) 안에 2개 이상의 아이템(Item)이 존재하여도 대표 상품 1개의 정보만 출력하였습니다.
  • 예를 들면 2개의 주문(Order)이 존재하고 각각 2개의 아이템(Item)이 존재할 때 총 4개의 아이템 목록이 출력되어야 하지만, 현재 상황은 각 주문당 1개의 아이템을 출력하여 총 2개의 아이템 목록이 출력되는 상황입니다.
  • 즉, 1개의 주문에 1개의 아이템만 출력되는 상황이라고 볼 수 있습니다.
  • userAJPA1 BOOKJPA2 BOOK 라는 2개의 아이템을 주문하였지만, 주문 내역에는 JPA1 BOOK 에 대한 정보밖에 볼 수 없는 상황입니다.

🧷 기존 HTML 코드

<tr th:each="item : ${orders}">
  <td th:text="${item.id}"></td>
  <td th:text="${item.member.name}"></td>
  <td th:text="${item.orderItems[0].item.name}"></td>
  <td th:text="${item.orderItems[0].orderPrice}"></td>
  <td th:text="${item.orderItems[0].count}"></td>
  <td th:text="${item.status}"></td>
  <td th:text="${item.orderDate}"></td>
  <td>
  <a th:if="${item.status.name() == 'ORDER'}" href="#"
     th:href="'javascript:cancel('+${item.id}+')'"
     class="btn btn-danger">CANCEL</a>
  </td>
</tr>
  • 기존의 HTML 코드의 4~6번째 줄 코드를 보면 item.orderItems[0] 로 코드가 작성되어 있습니다.
  • item.orderItems 목록에 존재하는 모든 아이템을 출력해야 하는데, 0번째 인덱스에 존재하는 아이템에 대한 정보만 출력한다는 것을 발견하였습니다.
  • 1개의 주문에 1개의 아이템만 출력되는 이유를 발견할 수 있었습니다.
  • 각 주문에 해당하는 모든 아이템(orderItem)을 출력하기 위해서는 1개의 반복문이 더 필요한 상황입니다.

📍 해결 방법

  • Controller, Service 등의 코드를 수정하지 않고 HTML 코드만 수정하여 문제를 해결할 수 있는 방법이 있습니다.
  • Thymeleaf의 <th:block> 템플릿을 이용하면 문제를 해결할 수 있습니다.
    • <th:block> 은 개발자가 원하는 속성을 지정할 수 있는 단순한 속성 컨테이너입니다.
    • Thymeleaf는 이러한 속성을 실행한 다음 내용이 아닌 블록을 단순히 사라지게 만듭니다.
    • 예를 들어 각 요소에 대해 이중 반복을 이용한 <tr> 테이블을 생성할 때 유용할 수 있습니다.
  • 이미 첫 번째 줄에 <tr th:each="item : ${orders}"> 반복문이 한번 사용되고 있고 각 주문(orders) 안에 존재하는 아이템(orderItem)에 대한 반복문을 또 적용해야 합니다.
  • 이 때 반복문은 적용할 수 있지만 실제 HTML에서는 이중으로 적용되지 않는 <th:block> 을 이용하면 문제를 해결할 수 있습니다.
  • 첫 번째 반복문은 주문 목록인 orders<th:block th:each="order : ${orders}">를 통해 각 주문(order) 별로 수행될 수 있도록 태그를 작성합니다.
  • 두 번째 반복문은 각 주문(order)을 <tr th:each="orderItem : ${order.orderItems}">를 통해 주문한 아이템(orderItem) 별로 출력이 수행될 수 있도록 태그를 작성합니다.

🧷 해결 방법

<th:block th:each="order : ${orders}">
  <tr th:each="orderItem : ${order.orderItems}">
    <td th:text="${order.id}"></td>
    <td th:text="${order.member.name}"></td>
    <td th:text="${orderItem.item.name}"></td>
    <td th:text="${orderItem.orderPrice}"></td>
    <td th:text="${orderItem.count}"></td>
    <td th:text="${order.status}"></td>
    <td th:text="${order.orderDate}"></td>
    <td>
      <a th:if="${order.status.name() == 'ORDER'}" href="#"
         th:href="'javascript:cancel('+${order.id}+')'"
         class="btn btn-danger">CANCEL</a>
    </td>
  </tr>
</th:block>

🧷 수정 후 결과

  • 처음 화면과는 다르게 userAJPA1 BOOKJPA2 BOOK 라는 2개의 아이템을 주문한 것을 확인할 수 있고, userBSPRING1 BOOKSPRING2 BOOK 라는 2개의 아이템을 주문한 것을 확인할 수 있습니다.

profile
목적 있는 글쓰기

0개의 댓글