10/23/2018

스프링 쇼핑몰 만들기 #23. 주문 하기, 주문 확인 기능 구현

스프링 쇼핑몰 만들기
- 깃허브 링크

카트에 담아둔 상품을 주문하는 기능입니다. 사용자가 주문한 상품은 관리자에게 전달되며, 관리자가 이를 확인하여 상품을 전달하면 됩니다.

cartList.jsp의 반복문 <c:forEach> 위에 코드를 추가합니다.

<c:set var="sum" value="0" />

반복문이 끝나는 </c:forEach> 위에 코드를 추가합니다.

<c:set var="sum" value="${sum + (cartList.gdsPrice * cartList.cartStock)}" />

이 코드로 카트 목록내 모든 상품의 가격이 저장됩니다.

목록 <ul> ~ </ul> 하단에 코드를 추가합니다.

<div class="listResult">
<div class="sum">
총 합계 : <fmt:formatNumber pattern="###,###,###" value="${sum}" />원
</div>
<div class="orderOpne">
<button type="button" class="orderOpne_bnt">주문 정보 입력</button>
</div>
</div>

추가한 요소에 대한 스타일을 추가합니다.

.listResult { padding:20px; background:#eee; }
.listResult .sum { float:left; width:45%; font-size:22px; }

.listResult .orderOpne { float:right; width:45%; text-align:right; }
.listResult .orderOpne button { font-size:18px; padding:5px 10px; border:1px solid #999; background:#fff;}
.listResult::after { content:""; display:block; clear:both; }

카트 리스트의 가장 아랫부분에 모든 상품의 가격을 더한 값과 주문 정보 입력 버튼이 생겼습니다.

주문 테이블을 생성합니다.

create table tbl_order (
    orderId     varchar2(50) not null,
    userId      varchar2(50) not null,
    orderRec    varchar2(50) not null,
    userAddr1   varchar2(20) not null,
    userAddr2   varchar2(50) not null,
    userAddr3   varchar2(50) not null,
    orderPhon   varchar2(30) not null,
    amount      number       not null,
    orderDate   Date         default sysdate,   
    primary key(orderId)
);

주문 고유번호(orderId), 수신자(orderRec), 주소 3가지(우편번호, 기본주소, 상세주소), 연락처, 총가격, 주문 날짜로 구성되어있습니다.

alter table tbl_order
    add constraint tbl_order_userId foreign key(userId)
    references tbl_member(userId);

주문 테이블과 맴버 테이블의 참조 설정입니다.

주문 상세 테이블을 생성합니다.

:
create table tbl_order_details (
    orderDetailsNum number       not null,
    orderId         varchar2(50) not null,
    gdsNum          number          not null,
    cartStock       number          not null,
    primary key(orderDetailsNum)
);

주문 상세 테이블은 카트 테이블에 있는 대부분의 데이터를 가져옵니다.

create sequence tbl_order_details_seq;

주문 상세 번호(orderDetailsNum)로 이용될 시퀀스입니다.

alter table tbl_order_details
    add constraint tbl_order_details_orderId foreign key(orderId)
    references tbl_order(orderId);

주문 상세 테이블과 주문 테이블의 참조 설정입니다.

주문 테이블과 주문 상세 테이블, 이렇게 두가지로 나누어진 이유는 정보의 구조 때문입니다.

하나의 주문에 여러개의 상품이 들어갈 수 있는데 만약 하나의 테이블로 처리하려고 한다면, 상품 6개가 들어있는 하나의 주문은 총 6개의 데이터가 들어가게됩니다.

이렇게되면 각 상품의 정보를 제외하곤 모두 중복 데이터이므로, 상당히 비효율적입니다. 하지만 두개의 테이블로 분류되었다면, 중복되는 데이터를 최소화하여 관리할 수 있습니다.

새로운 테이블을 생성했으니, 테이블을 기반으로 VO를 생성합니다.

매퍼에 쿼리를 추가합니다.

<!-- 주문 정보 -->
<insert id="orderInfo">
insert into tbl_order(orderId, userId, orderRec, userAddr1, userAddr2, userAddr3, orderPhon, amount)
    values(#{orderId}, #{userId}, #{orderRec}, #{userAddr1}, #{userAddr2}, #{userAddr3}, #{orderPhon}, #{amount})
</insert>
   
<!-- 주문 상세 정보 --> 
<insert id="orderInfo_Details">
insert into tbl_order_details(orderDetailsNum, orderId, gdsNum, cartStock)
    select tbl_order_details_seq.nextval, #{orderId}, gdsNum, cartStock
        from tbl_cart   
</insert>

주문 상세 정보의 쿼리는 조금 다른 쿼리입니다.

데이터를 삽입하는 insert 쿼리는 일반적으로 insert into [테이블명] (컬럼1, 컬럼2 ...) values (데이터1, 데이터 2...); 처럼 되어있는데, 이번에 사용한건 insert into [테이블명] (컬럼1, 컬럼2 ...) select 데이터1, 데이터 2 ... from [테이블명] 으로, values 대신 테이블의 select문이 들어가있습니다.

insert select 문이라고 하며, select 에 있는 다수의 데이터를 입력할 수 있습니다.

DAO와 Service를 작성합니다.

컨트롤러에 주문용 메서드를 추가합니다.

// 주문
@RequestMapping(value = "/cartList", method = RequestMethod.POST)
public void order(HttpSession session, OrderVO order, OrderDetailVO orderDetail) throws Exception {
logger.info("order");

MemberVO member = (MemberVO)session.getAttribute("member");
String userId = member.getUserId();

service.orderInfo(order);
service.orderInfo_Details(orderDetail);
}

뷰(view. jsp부분)에서 작업을 하지 못해서 아직은 작동되지 않는 컨트롤러입니다.

cartList.jsp에 폼 <form> 을 추가하여 컨트롤러로 데이터를 전송하기 위한 준비를 합니다.

<div class="orderInfo">
<form role="form" method="post" autocomplete="off">

<input type="hidden" name="amount" value="${sum}" />

<div class="inputArea">
<label for="">수령인</label>
<input type="text" name="orderRec" id="orderRec" required="required" />
</div>

<div class="inputArea">
<label for="orderPhon">수령인 연락처</label>
<input type="text" name="orderPhon" id="orderPhon" required="required" />
</div>

<div class="inputArea">
<label for="userAddr1">우편번호</label>
<input type="text" name="userAddr1" id="userAddr1" required="required" />
</div>

<div class="inputArea">
<label for="userAddr2">1차 주소</label>
<input type="text" name="userAddr2" id="userAddr2" required="required" />
</div>

<div class="inputArea">
<label for="userAddr3">2차 주소</label>
<input type="text" name="userAddr3" id="userAddr3" required="required" />
</div>

<div class="inputArea">
<button type="submit" class="order_btn">주문</button>
<button type="button" class="cancel_btn">취소</button>
</div>

</form>
</div>

추가된 요소에 대한 스타일을 추가합니다.

.orderInfo { border:5px solid #eee; padding:20px; }
.orderInfo .inputArea { margin:10px 0; }
.orderInfo .inputArea label { display:inline-block; width:120px; margin-right:10px; }
.orderInfo .inputArea input { font-size:14px; padding:5px; }
#userAddr2, #userAddr3 { width:250px; }

.orderInfo .inputArea:last-child { margin-top:30px; }
.orderInfo .inputArea button { font-size:20px; border:2px solid #ccc; padding:5px 10px; background:#fff; margin-right:20px;}

주문 입력칸은 주문 정보 입력 버튼을 클릭했을 때만 보일 예정이므로

스타일에서 .orderInfodisplay:none; 을 추가합니다.

주문 정보 입력 버튼 아래에 스크립트를 추가하고

<script>
$(".orderOpne_bnt").click(function(){
$(".orderInfo").slideDown();
$(".orderOpne_bnt").slideUp();
});
</script>

주문 입력란의 취소 버튼 아래에 스크립트를 추가합니다.

<script>
$(".cancel_btn").click(function(){
$(".orderInfo").slideUp();
$(".orderOpne_bnt").slideDown();
});
</script>

주문 정보 입력 버튼을 클릭하면 숨겨져있던 주문 입력란이 나타나면서 버튼이 사라지게되고, 주문 입력란의 취소 버튼을 클릭하면 주문 입력란이 사라지면서 주문 정보 입력 버튼이 나타나게됩니다.

이제 컨트롤러에 코드를 마저 작성하여 완성합니다.

// 주문
@RequestMapping(value = "/cartList", method = RequestMethod.POST)
public String order(HttpSession session, OrderVO order, OrderDetailVO orderDetail) throws Exception {
logger.info("order");

MemberVO member = (MemberVO)session.getAttribute("member");
String userId = member.getUserId();

Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
String ym = year + new DecimalFormat("00").format(cal.get(Calendar.MONTH) + 1);
String ymd = ym +  new DecimalFormat("00").format(cal.get(Calendar.DATE));
String subNum = "";

for(int i = 1; i <= 6; i ++) {
subNum += (int)(Math.random() * 10);
}

String orderId = ymd + "_" + subNum;

order.setOrderId(orderId);
order.setUserId(userId);

service.orderInfo(order);

orderDetail.setOrderId(orderId);
service.orderInfo_Details(orderDetail);

service.cartAllDelete(userId);

return "redirect:/shop/orderList";
}

달력 메서드(Calendar)이용하여 연/월/일을 추출하고 6자리의 랜덤 숫자로 만들어진 subNum을 더하여 [날짜]_[랜덤숫자] 로 이루어진, 최대한 중복되지 않는 고유한 문자열을 생성합니다.

subNum는 절대로 중복되지 않는다는 보장은 없지만, 중복될 확률은 10^6이며 매일매일 날짜로 구분되기 때문에 중복될 확률은 매우 낮습니다. 이렇게 랜덤으로하지 않고 UUID등 다른 방법을 사용해도 무관합니다.

테스트용으로 임의의 값을 넣어서 주문 버튼을 클릭해봅니다.

컨트롤러에 orderList 메서드가 없기 때문에 404 에러가 발생하게됩니다.

하지만 데이터는 잘 입력되었습니다.

데이터가 주문 테이블과 주문 상세 테이블로 넘어갔다면, 더이상 카트 테이블에 있는 데이터는 불필요하므로 삭제시켜야합니다.

매퍼에 삭제 쿼리를 추가합니다.

<!-- 카트 비우기 -->
<delete id="cartAllDelete">
delete tbl_cart
    where userId = #{userId}
</delete>

DAO와 Service를 작성합니다.

주문용 메서드에 service.cartAllDelete(userId); 를 추가합니다.

주문 테이블과 주문 상세 테이블을 생성한 뒤 카트 테이블의 데이터를 모두 삭제합니다.

이제 다시 주문 정보를 입력하고 주문 버튼을 클릭합니다.

카트에 있는 모든 데이터가 삭제되었음을 알 수 있습니다.

주문 테이블과 주문 상세 테이블에는 데이터가 잘 입력된걸 확인할 수 있습니다. (스크린샷은 몇번 테스트를 해서 결과가 조금 다릅니다)

이제 주문 목록을 볼 수 있도록 매퍼에 쿼리를 추가합니다.

<!-- 특정 유저의 주문 목록 -->
<select id="orderList" resultType="com.kubg.domain.OrderVO">
select
    orderId, userId, orderRec, userAddr1, userAddr2, userAddr3, orderPhon, amount, orderDate
from tbl_order 
    where userId = #{userId}
</select>

DAO와 Service를 작성합니다.

컨트롤러에 주문 목록용 메서드를 작성합니다.

// 주문 목록
@RequestMapping(value = "/orderList", method = RequestMethod.GET)
public void getOrderList(HttpSession session, OrderVO order, Model model) throws Exception {
logger.info("get order list");

MemberVO member = (MemberVO)session.getAttribute("member");
String userId = member.getUserId();

order.setUserId(userId);

List<OrderVO> orderList = service.orderList(order);

model.addAttribute("orderList", orderList);
}

list.jsp를 복사/붙여넣기 한 뒤 이름을 orderList.jsp로 바꾸고 <section id="orderList"> 내부에 코드를 추가합니다.

<section id="content">

<ul class="orderList">
<c:forEach items="${orderList}" var="orderList">
<li>
<div>
<p><span>주문번호</span><a href="/shop/orderView?n=${orderList.orderId}">${orderList.orderId}</a></p>
<p><span>수령인</span>${orderList.orderRec}</p>
<p><span>주소</span>(${orderList.userAddr1}) ${orderList.userAddr2} ${orderList.userAddr3}</p>
<p><span>가격</span><fmt:formatNumber pattern="###,###,###" value="${orderList.amount}" /> 원</p>
</div>
</li>
</c:forEach>
</ul>

</section>

이때 주문번호는 /shop/orderView?n=[orderId] 형태로 만들어지며, orderId가 들어가는 n의 값을 컨트롤러에서 사용할 수 있습니다.

추가된 요소에 대한 스타일을 추가합니다.

<style>
/*
section#content ul li { display:inline-block; margin:10px; }
section#content div.goodsThumb img { width:200px; height:200px; }
section#content div.goodsName { padding:10px 0; text-align:center; }
section#content div.goodsName a { color:#000; }
*/
section#content ul li { border:5px solid #eee; padding:10px 20px; margin-bottom:20px; }
section#content .orderList span { font-size:20px; font-weight:bold; display:inline-block; width:90px; margin-right:10px; }
</style>

orderList.jsp에 바로 접속할 수 있도록, 메뉴가 있는 nav.jsp에 코드를 추가합니다.

<li>
<a href="/shop/orderList">주문 리스트</a>
</li>

이제 orderList로 접속하면 각 주문이 구분되어 위처럼 출력됩니다.

주문 번호를 클릭하면 해당 주문에 대한 상세 정보를 볼 수 있게 할 예정입니다.

주문 테이블, 주문 상세 테이블, 상품 테이블 이렇게 3개의 테이블을 조인하여 모든 정보가 표시될 수 있도록 쿼리를 작성했습니다.

쿼리를 기반으로 새로운 VO를 생성합니다. OrderVO와 OrderDetailsVO의 모든 값, GoodsVO의 gdsNum, gdsThumbImg, gdsPrice가 포함되어있는 VO입니다.

매퍼에 쿼리를 추가합니다.

<!-- 특정 주문 목록 -->
<select id="orderView" resultType="com.kubg.domain.OrderListVO">
select
    o.orderId, o.userId, o.orderRec, o.userAddr1, o.userAddr2, o.userAddr3, o.orderPhon, o.amount, o.orderDate,
    d.orderDetailsNum, d.gdsNum, d.cartStock,
    g.gdsName, g.gdsThumbImg, g.gdsPrice
from tbl_order o
        inner join tbl_order_details d
            on o.orderId = d.orderId
        inner join tbl_goods g
            on d.gdsNum = g.gdsNum
    where o.userId = #{userId}
        and o.orderId = #{orderId}
</select>

DAO와 Service를 작성합니다.

컨트롤러에 주문 목록용 메서드를 추가합니다.

// 주문 상세 목록
@RequestMapping(value = "/orderView", method = RequestMethod.GET)
public void getOrderList(HttpSession session,
@RequestParam("n") String orderId,
OrderVO order, Model model) throws Exception {
logger.info("get order view");

MemberVO member = (MemberVO)session.getAttribute("member");
String userId = member.getUserId();

order.setUserId(userId);
order.setOrderId(orderId);

List<OrderListVO> orderView = service.orderView(order);

model.addAttribute("orderView", orderView);
}

URL에서 'n'에 지정된 값을 받아와서 orderId로 사용합니다.

list.jsp를 복사/붙여넣기 한 뒤 이름을 ordereView.jsp로 변경한 다음 코드를 추가합니다.

<section id="content">

<div class="orderInfo">
<c:forEach items="${orderView}" var="orderView" varStatus="status">

<c:if test="${status.first}">
<p><span>수령인</span>${orderView.orderRec}</p>
<p><span>주소</span>(${orderView.userAddr1}) ${orderView.userAddr2} ${orderView.userAddr3}</p>
<p><span>가격</span><fmt:formatNumber pattern="###,###,###" value="${orderView.amount}" /> 원</p>
</c:if>

</c:forEach>
</div>

<ul class="orderView">
<c:forEach items="${orderView}" var="orderView">
<li>
<div class="thumb">
<img src="${orderView.gdsThumbImg}" />
</div>
<div class="gdsInfo">
<p>
<span>상품명</span>${orderView.gdsName}<br />
<span>개당 가격</span><fmt:formatNumber pattern="###,###,###" value="${orderView.gdsPrice}" /> 원<br />
<span>구입 수량</span>${orderView.cartStock} 개<br />
<span>최종 가격</span><fmt:formatNumber pattern="###,###,###" value="${orderView.gdsPrice * orderView.cartStock}" /> 원                 
</p>
</div>
</li>
</c:forEach>
</ul>
</section>

추가한 요소에 대한 스타일을 추가합니다.

<style>
/*
section#content ul li { display:inline-block; margin:10px; }
section#content div.goodsThumb img { width:200px; height:200px; }
section#content div.goodsName { padding:10px 0; text-align:center; }
section#content div.goodsName a { color:#000; }
*/
.orderInfo { border:5px solid #eee; padding:10px 20px; margin:20px 0;}
.orderInfo span { font-size:20px; font-weight:bold; display:inline-block; width:90px; }

.orderView li { margin-bottom:20px; padding-bottom:20px; border-bottom:1px solid #999; }
.orderView li::after { content:""; display:block; clear:both; }

.thumb { float:left; width:200px; }
.thumb img { width:200px; height:200px; }
.gdsInfo { float:right; width:calc(100% - 220px); line-height:2; }
.gdsInfo span { font-size:20px; font-weight:bold; display:inline-block; width:100px; margin-right:10px; }
</style>

이제 주문 리스트에서 주문 번호를 클릭하게되면, 해당 주문에 대한 상품이 목록이 출력됩니다.

다른 상품을 카트에 넣고, 카트 내용을 주문해봅니다.

주문이 2개 이상이어도 정상적으로 출력됩니다.

게시물 수정
  1. 여러 상품을 카테고리에 담았을때 총 합계 금액에 장바구니에 담긴 상품 모두의 가격이 뜹니다.
    상품 주문 시에도 장바구니에서 체크한 상품만 담기는게 아니라 장바구니에 담긴 상품이 모두 주문되고요.
    이 부분에 대한 처리는 따로 하지 않으신건지요?..

    답글삭제
    답글
    1. 안녕하세요?

      먼저... 이 만들다 말아버린-_- 쇼핑몰에서, 카트 화면의 체크박스는 삭제를 위한 체크박스입니다.
      구입(주문)은 현재 리스트에 있는 모든 상품을 대상으로 진행됩니다.

      같은 이유로 총 합계 금액은 '선택한 상품의 합계'가 아니라 '현재 카트에 있는 모든 상품의 합계'가 됩니다.

      삭제
  2. 작성자가 댓글을 삭제했습니다.

    답글삭제
  3. 안녕하세요

    <!-- 주문 상세 정보 -->
    <insert id="orderInfo_Details">
    insert into tbl_order_details(orderDetailsNum, orderId, gdsNum, cartStock)
    select tbl_order_details_seq.nextval, #{orderId}, gdsNum, cartStock
    from tbl_cart
    </insert>
    이부분이

    insert into tbl_order_details(orderDetailsNum, orderId, gdsNum, cartStock)
    select tbl_order_details_seq.nextval, orderId, gdsNum, cartStock
    from tbl_cart where orderId=#{orderId}


    이런식으로 해야된다고 생각했는데 아닌가요,,ㅠ

    답글삭제
    답글
    1. 안녕하세요?

      orderInfo_Details의 쿼리는 현재의 데이터를 그대로 복사하는 용도이므로 orderInfo_Details의 쿼리나 말씀하신 쿼리를 사용하셔도 무관합니다.

      삭제
  4. 안녕하세요!
    혹시 주문상세테이블에서 goodsNum값도 참조키로 지정해야하는거 아닌가요? 참조키로 지정안해도 문제가없나요?

    답글삭제
    답글
    1. 안녕하세요? 방문해주셔서 감사합니다.
      말씀하신대로 상품번호값도 같이 참조키로 지정해주셔야합니다.
      저는 깜빡하고 넘어간것 같은데..;

      실행 자체에는 이상이 없겠으나 데이터 베이스의 특성상 참조키로 지정해주시는게 옳은 방법입니다.

      삭제
  5. //주문 상세 정보
    public void orderInfo_Details(OrderDetailVO orderDetail) throws Exception;
    이부분만 추가하면 404 오류가 뜹니다. 콘솔창에도 오류는 안뜹니다.

    답글삭제
    답글
    1. 안녕하세요? 방문해주셔서 감사합니다.

      인터페이스만 추가하신걸로 404에러는 뜨지 않았을텐데..
      관련 페이지까지 전부 구현해도 그런가요?

      삭제
  6. 익명1/11/2021

    주문상세정보 쿼리에서, from tbl_cart 이렇게 하면, 다른 아이디로 장바구니에 담은 것도 같이 담기는 거 아닌가요..? where로 제한을 둬야하는 게 아닌지...

    답글삭제
    답글
    1. 안녕하세요? 방문해주셔서 감사합니다.

      insert에 있는 from tbl_cart 라면... 인서트할때 order_id를 입력하기 때문에 주문테이블에서 특정지을 수 있습니다.

      삭제
  7. 익명2/19/2021

    안녕하세요 블로그에 올려주신 자료로 공부하고 있습니다 정말 감사합니다.



    insert into tbl_order_details(orderDetailsNum, orderId, gdsNum, cartStock)
    select tbl_order_details_seq.nextval, #{orderId}, gdsNum, cartStock
    from tbl_cart


    이 부분에서 ORA-0001 : unique constraint 에러가 발생했습니다
    검색해보니 무결성 제약조건이라고 나오는데 key값이 중복되지않아야 한다고 하는데
    어떻게 해결해야 할 지 모르겠습니다..

    답글삭제
    답글
    1. 안녕하세요? 방문해주셔서 감사합니다.

      tbl_order_details 테이블의 orderDetailsNum이 중복되지 말아야하며 그렇기 때문에 시퀀스를 이용하여 관리하는건데..

      select tbl_order_details_seq.currval from dual로 현재 시퀀스 값이 tbl_order_details 에 등록되어있는건지 확인해보고, 등록되어있다면 해당 값을 지우시면 될 것 같습니다.

      삭제
    2. 익명2/19/2021

      답변해주신대로 했더니 정상적으로 저장되었습니다 알려주셔서 고맙습니다 ㅠㅠㅠ
      염치없지만 한가지만 더 질문 드려도 될까요
      아래는 제가 처음에 작성한 쿼리입니다

      <insert id="orderInfo_Details">
      <selectKey resultType="int" keyProperty="orderDetailsNum" order="BEFORE">
      SELECT tbl_order_details_seq.nextval FROM dual
      </selectKey>
      insert into tbl_order_details(orderDetailsNum, orderId, gdsNum, cartStock)
      select #{orderDetailsNum}, #{orderId}, gdsNum, cartStock
      from tbl_cart
      </insert>

      이렇게 작성한 후 오류가 나서 kuzuro님의 답변, 블로그의 쿼리문과 똑같이 작성하니 실행이 잘 되었는데요
      위의 쿼리문에서 잘못된 부분이 궁금합니다..

      삭제
    3. tbl_order_details에는 현재 시퀀스값(정확하게하면 tbl_order의 order_id)을 따라가야하는데
      tbl_order_details_seq.nextval에서 시퀀스 값을 증가시키므로, tbl_order에 참조할 데이터가 없으므로 생기는 오류로 보입니다.

      삭제
    4. 익명2/20/2021

      그런거였군요~ 궁금증을 해결해주셔서 고맙습니다

      삭제
  8. 장바구니 총합 구하는 거 찾는 중이었는데.. 정말 감사합니다 ㅠㅡㅠ

    답글삭제
  9. mysql로 구현중인데 insert select문을 어떤 방식으로 구현 해야할지 감이 안잡히네요..ㅠ

    INSERT INTO orderdetails(orderDetailsNum, orderId, gdsNum, cartStock)

    select #{orderDetailsNum}, #{orderId}, gdsNum, cartStock
    from cart

    이런식으로 selectKey로 사용하는데 이것도 아닌거 같고... 어느 방식으로 해결을 해야할까요..ㅠㅠ

    답글삭제
    답글
    1. 안녕하세요? 방문해주셔서 감사합니다.

      본문에서는 다음시퀀스 값을 받아오는데, mysql에서 사용하는 auto_increment의 경우는 자동으로 값이 증가하므로, 해당 컬럼을 제외시키시면 될것 같습니다

      삭제
  10. 익명8/21/2021

    따라해보진않고 그냥 슥 읽고있어서 정확하진 않지만 궁금해서 코멘트 드립니다

    insert select 문에 아무 조건없이 tbl_cart 를 가져오면
    다른 사람의 카트리스트도 가져와버리는거 아닌가요 ?

    나중에 한번 직접 만들어봐야겠네요 ㅎㅎ 좋은글 감사합니다

    답글삭제
    답글
    1. 안녕하세요? 방문해주셔서 감사합니다.

      만든지 오래되어서 가물가물한데(...)
      오더 번호(order_id)로 구분이 되던걸로 기억-_-...합니다.

      삭제
  11. 작성하신 코드 그대로 따라해봤는데

    주문 번호 클릭후 주문상세정보(orderView) 확인시

    주문한 상품 외의 cart에 담겨있던 모든 상품이 출력되는데 해결 방법이 있을까요 ㅠㅠ

    답글삭제
    답글
    1. 안녕하세요? 방문해주셔서 감사합니다.

      오래된거라 좀 가물가물한데; 주문번호-> 상세정보에서 주문번호를 통해 상품정보를 특정 지을 수 있습니다.
      아마 이 조건문에 데이터가 제대로 들어가지 않았을걸로 추측..이 됩니다만
      좀 가물가물하네요=_=;

      삭제
    2. 주문정보 입력시에 다른 userId 의 cart 데이터가 같이 입력되어 주문이 되는것을 확인했습니다.

      그래서 주문상세정보(orderView) 에 다른아이디의 cart에 있던 데이터까지 뿌려지는것 같은데..

      코드는 같게 입력했습니다만.. 조건을 어떻게 변경해야하는지..

      삭제
  12. 주문 취소에 대한 기능 구현에 대해 알고싶습니다 부탁드려도될까요?

    답글삭제
    답글
    1. 안녕하세요? 방문해주셔서 감사합니다.

      너무 늦게 확인했지만.. 언젠가(...) 업데이트하면서 구현하도록 하겠...습니다ㅠㅠ

      삭제