D+42::쇼핑몰_장바구니목록에서 선택 상품 구매

Am.Vinch·2022년 8월 24일
0

20220824_wed

실습내용

  • 상품구매상세정보 기능 구현
  • 상품구매정보는 1개이지만 구매상세정보는 여러개가능하다.
    • 예시)
    • 어떤사람이 상품1개 구매할때
      BUY_CODE => BUY_005
      BUY_DETAIL_CODE => BUY_005_01
    • 어떤사람이 상품2개 구매할 때
      BUY_CODE => BUY_006
      BUY_DETAIL_CODE => BUY_006_01,BUY_006_02
  • 구매상세정보는 트랜잭션 처리를 해야한다!
  • DB_구매한 사람의 구매상세 테이블
//테이블 생성
CREATE TABLE BUY_DETAIL(
    BUY_DETAIL_CODE VARCHAR2(100) PRIMARY KEY --EX) BUY_001_01,BUY_001_02,BUY_001_03: 어느 한사람이 3개구매/BUY_002_01,BUY_002_02:다른 사람이 2개구매
    , ITEM_CODE VARCHAR2(50) REFERENCES SHOP_ITEM(ITEM_CODE)
    , BUY_CNT NUMBER NOT NULL
    , BUY_CODE REFERENCES SHOP_BUY(BUY_CODE)
);
//조회
SELECT * FROM BUY_DETAIL;
  • buy-mapper
    :구매상세정보 등록
	 <insert id="insertBuyDetail" >
	INSERT INTO BUY_DETAIL(
		BUY_DETAIL_CODE
		,ITEM_CODE
		,BUY_CNT
		,BUY_CODE
	) VALUES(
		 #{buyCode}||'_01'
		,#{itemCode}
		,#{buyCnt}
		,#{buyCode}
	)
	</insert> 
  • BuyDetailDTO.java
package dto;

public class BuyDetailDTO {
	private String buyDetailCode;
	private String itemCode;
	private int buyCnt;
	private String buyCode;
	
	public String getBuyDetailCode() {
		return buyDetailCode;
	}
	public void setBuyDetailCode(String buyDetailCode) {
		this.buyDetailCode = buyDetailCode;
	}
	public String getItemCode() {
		return itemCode;
	}
	public void setItemCode(String itemCode) {
		this.itemCode = itemCode;
	}
	public int getBuyCnt() {
		return buyCnt;
	}
	public void setBuyCnt(int buyCnt) {
		this.buyCnt = buyCnt;
	}
	public String getBuyCode() {
		return buyCode;
	}
	public void setBuyCode(String buyCode) {
		this.buyCode = buyCode;
	}
	@Override
	public String toString() {
		return "BuyDetailDTO [buyDetailCode=" + buyDetailCode + ", itemCode=" + itemCode + ", buyCnt=" + buyCnt
				+ ", buyCode=" + buyCode + "]";
	}
}
  • BuyService.java
    • 구매상세정보는 구매정보등록에 한꺼번에 작성해야한다. 그래서 따로 작성 x
    • 왜? 트랜잭션처리위해서(insert이기때문)
    • 구매상세정보등록을 실행시키기위해서는 구매상세정보DTO에 담아있는 매개변수 빈값들을 가져와야하기때문에 BuyDetailDTO를 추가해서 작성해준다.
      void insertBuy(BuyDTO buyDTO,BuyDetailDTO buyDetailDTO);
  • BuyServiceImpl.java
    :트랜잭션처리위해서 try-catch문으로 작성해줘야 한다!
  //구매정보등록
    @Override
	public void insertBuy(BuyDTO buyDTO,BuyDetailDTO buyDetailDTO) {
		try {//오류가 발생할 수 있는 쿼리문
			sqlSession.insert("buyMapper.insertBuy",buyDTO);
			//트랜잭션 처리는 하나의 메소드 안에 두개 동시에 처리하도록 연달아 작성한다
			//구매상세정보 등록
			sqlSession.insert("buyMapper.insertBuyDetail",buyDetailDTO);
			sqlSession.commit();
		} catch (Exception e) {//오류가나면 실행
			sqlSession.rollback();//오류가발생하면 롤백시킨다.
			e.printStackTrace();//오류설명간단히
			
		}
	}
  • BuyController
protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//한글 인코딩 처리
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
	
		String requestURI = request.getRequestURI();
		String contextPath = request.getContextPath();
		String command = requestURI.substring(contextPath.length());
		System.out.println("command = " + command);
		
		String page = "jsp/template/template.jsp";
		boolean isRediect = false;
		String contentPage = "";
		
		//구매정보 insert
		if(command.equals("/insertBuy.buy")) {
			String itemCode = request.getParameter("itemCode");
			int putCnt = Integer.parseInt(request.getParameter("putCnt"));
			
			//다음에 들어갈 BUY_CODE 조회
			String buyCode = buyService.selectNextBuyCode();
			
			HttpSession session = request.getSession();
			MemberDTO loginInfo = (MemberDTO)session.getAttribute("loginInfo");
			String memId = loginInfo.getMemId();

			BuyDTO buyDTO = new BuyDTO();
			buyDTO.setItemCode(itemCode);
			buyDTO.setBuyCode(buyCode);
			buyDTO.setPutCnt(putCnt);
			buyDTO.setMemId(memId);
			
			BuyDetailDTO buyDetailDTO = new BuyDetailDTO();
			buyDetailDTO.setBuyCode(buyCode);
			buyDetailDTO.setItemCode(itemCode);
			buyDetailDTO.setBuyCnt(putCnt);// 구매상세정보테이블 컬럼명은 BuyCnt이지만 위의 구매정보테이블 컬럼명은 putCnt 이기때문에 매개변수는 putCnt로 사용한다
			
			//구매 정보 insert
			buyService.insertBuy(buyDTO, buyDetailDTO);
            
			page ="itemList.it";
			isRediect = false;
		}
  • 프로젝트 실행 -> 상품선택 -> 수량입력 -> '구매하기' 버튼 클릭-> 디비에서 구매상세정보 테이블결과 조회->입력된 정보 데이터 등록 확인

실습내용

  • 하지만, 우리가 위에 만든 코드를 사용하면 장바구니에서 사용할 때 문제가 발생할 수 있어서 수정이 필요하다!!
  • 장바구니 구매하기 기능 구현
  • 장바구니페이지는 지난번 처럼 자바스크립트를 사용하여 구현한다.( cart_list.js)
  • 자바스크립트 쿼리 작성후 실행하면 개발자모드로 콘솔 확인
  • cart_list.js
//장바구니에서 선택한 상품 구매하기 기능 구현
	//넘겨야하는 데이터: 내가 체크한 ITEM_CODE,BUY_CNT,BUY_CODE, //TOTAL_PRICE(상관없어서 넘기지않음)
	//ITEM_CODE, BUY_CNT, totalPrice..
	
	//총가격(장바구니전체):우선,내가 체크된 체크박스와 같은 줄에있는 '총가격(상품별)'만 가져간다. 그리고 그들끼리만 더한다.
	const checkedBoxes = document.querySelectorAll('.chk:checked'); // 여러개가지고 오니까 all 사용
	let totalPrice = 0; // 변하지않기때문 let 사용한다.
	
	//반복문사용해서 각 체크박스들의 각 총가격을 빼낸다
	for(const checkBox of checkedBoxes){//체크된 checkedBoxes들 중에 하나씩 뺀다 그것을 checkBox 라고한다.
		//자식,부모 태그 선택 함수
		//parentElement() : 가장 가까운 부모태그를 찾아가는 함수
		//children : 가장 가까운 자식태그를 찾아가는 함수
		//previousSibling : 이전 형제 노드를 찾아 감. 제이쿼리는 prev()
		//nextElementSibling() : 다음 형제 노드를 찾아 감. 
		//closest() : 가장 가까운 상위태그를 찾아가는 함수

		const price = checkBox.closest('tr').children[5].innerText; //체크박스기준 감싸고있는 것중 가장가까운 tr 태그에서 6번째 자식태그안에 내용
		
		//총가격은 각 총가격에 가격을 누적시킨다.
		totalPrice = totalPrice + parseInt(price); 
	}
		console.log(totalPrice);//totalPrice 출력
}
  • cart_list.jsp
</head>
<body>
<table>
	<thead>
		<tr>
			<td><input type="checkbox" id="allChk" checked="checked"></td>
			<td>상품이미지</td>
			<td>상품명</td>
			<td>단가</td>
			<td>수량</td>
			<td>총 가격</td>
			<td>등록 일자</td>
		</tr>
	</thead>
	<tbody>
		<c:forEach var="cart" items="${cartList}"> 
			<tr>
				<td><input type="checkbox" class="chk" checked></td><!-- 똑같은 값이 반복되면 id값 안되고 class값으로! -->
				<td><!-- cart-mapper 페이지를 보고 판단하고 작성하기!!! -->
					<img width="100px" height="130px" src="images/${cart.imgDTO.attachedName}"></td>
					<!-- cart-mapper 페이지를 보고 판단하고 작성하기!!! -->
				<td>${cart.itemDTO.itemName }</td>
				<!-- 단가 쉼표 표시로 나오도록 만들기 -->
				<td><fmt:formatNumber pattern="₩#,##0" value="${cart.itemDTO.itemPrice }"/> </td>
				<td>${cart.putCnt }</td>
				<!-- 총가격 쉼표 표시로 나오도록 만들기 -->
				<td>${cart.totalPrice }</td>
				<td>${cart.putDate }</td>
			</tr>
		 </c:forEach> 
	</tbody>
</table>
<div class="btns" align="center" >
	<input class="btn" type="button" value="선택구매"  onclick="goBuy();" ><!-- 자바스크립트로 가져간다. -->
	<input class="btn" type="button" value="선택삭제" >
</div>
<div>
	<script type="text/javascript" src="js/cart/cart_list.js?ver=08"></script><!-- 자바스크립트 수정할 때마다 변경해줘야 실행가능함 -->
</div>
</body>
</html>
  • 결과
    • 선택한 상품의 총가격(상품별)의 장바구니 전체 총 가격을 개발자모드 콘솔창에서 확인

실습내용

  • 앞에서 구한 총가격의 합을 이제는 페이지 화면에 띄우도록 구현한다.
  • 이미 체크박스 위에 forEach문의 cart에는 아이템코드가 담겨져있으니 체크박스에서는 이를 객체명으로 빼와서 value값으로 뽑아온다.
<c:forEach var="cart" items="${cartList}"> 
	<td><input type="checkbox" class="chk" value="${cart.itemCode }"></td>

JAVASCRIPT 자바스크립트 - 문자열 자르기 (split, substr, substring, slice)

JavaScript에서 문자열을 자를 때, split(), substr(), substring(), slice()를 사용할 수 있습니다.
이 함수들이 어떻게 문자열을 자르는지 사용 방법을 소개합니다.

  • split() : 구분자로 문자열 분리하여 배열로 리턴
  • substr() : 특정 Index에서 원하는 길이만큼 잘라서 문자열로 리턴
  • substring() : 시작 Index에서 끝 Index 전까지 문자열을 잘라서 리턴
  • slice() : substring과 비슷하지만 살짝 다른 메소드
  • 문제점) 아이템코드 나열한 문자열를 구하는데 총 결과값에서 마지막 ','는 없애려고한다.
  • 해결) 어떻게 하냐? 문자열자르기 함수를 이용하자.
    ex)ITEM_001,ITEM_002,
    str.substr(0,문자열 str의 길이);
    -> str문자열의 길이 우리가 확실히 모른다! 어떻게 길게 나올지 모르니!
const str = 'abcdefg'
 str.substr(3); ->'defg'
 str.substr(3,2); ->'de'
  • 결과 확인
    : 구매하기 버튼 클릭 후 개발자모드 콘솔창 확인 가능
    <input type="hidden" name="itemCode" id="itemCode" value="ITEM_001 ,ITEM_004 ,ITEM_005">
    <input type="hidden" name="buyCnt" id="buyCnt" value="10,1,1">

(최종)장바구니목록에서 선택 구매 결과

  • cart_list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri= "http://java.sun.com/jsp/jstl/core" %> 	
<%@ taglib prefix="fmt"  uri="http://java.sun.com/jsp/jstl/fmt"%>    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
table{
	width: 80%;
	border: 3px solid white;
	border-collapse: collapse;
	background-color: #F1F1F1;
	margin: 0 auto;
	text-align: center;
}
tr,td{
border: 3px solid none;
	border-collapse: collapse;
	background-color: #F1F1F1;
	margin: 0 auto;
	text-align: center;
}
table > tr:first-child {
	background-color: #F1F1F1;
	
}
thead{
border: 5px solid white;
}
.btns{
	width: 100%;
	margin-top: 20px;
	
}
input([type="button"]){
	height: 40px;
	width: 150px;
	
}

</style>
</head>
<body>
<table>
	<thead>
		<tr>
			<td><input type="checkbox" id="allChk" checked="checked"></td>
			<td>상품이미지</td>
			<td>상품명</td>
			<td>단가</td>
			<td>수량</td>
			<td>총 가격</td>
			<td>등록 일자</td>
		</tr>
	</thead>
	<tbody>
		<c:forEach var="cart" items="${cartList}"> 
			<tr>
				<!-- 똑같은 값이 반복되면 id값 안되고 class값으로! -->
				<!-- 이미 위에서 cart에는 아이템코드가 담겨져있으니 체크박스에서는 이를 객체명으로 빼와서 value값으로 뽑아온다. -->
				<td><input type="checkbox" class="chk" value="${cart.itemCode}"></td>
				<td><!-- cart-mapper 페이지를 보고 판단하고 작성하기!!! -->
					<img width="100px" height="130px" src="images/${cart.imgDTO.attachedName}"></td>
					<!-- cart-mapper 페이지를 보고 판단하고 작성하기!!! -->
				<td>${cart.itemDTO.itemName }</td>
				<!-- 단가 쉼표 표시로 나오도록 만들기 -->
				<td><fmt:formatNumber pattern="₩#,##0" value="${cart.itemDTO.itemPrice }"/> </td>
				<td>${cart.putCnt }</td>
				<!-- 총가격 쉼표 표시로 나오도록 만들기 -->
				<td>${cart.totalPrice }</td>
				<td>${cart.putDate }</td>
			</tr>
		 </c:forEach> 
	</tbody>
</table>
<div class="btns" align="center">
	<form action="insertBuys.buy" method="post">
		<!--value값을 빈값으로 두어도 저장후 화면에서 구매하기클릭하면 팝업창으로 총가격들이 뜬다.  -->
		<!-- input태그에서 name속성사용하는 이유? 자바로 데이터 가져가기 위해서 -->
		<!-- input태그에서 id속성사용하는 이유? 자바스크립트로 데이터 가져가기 위해서 -->
		<input type="hidden" name="totalPrice" id="totalPrice" value="">
		<!-- 체크된 갯수만큼 아이템코드별로 input태그를 만들어야한다. -->	
		<input type="hidden" name="itemCode" id="itemCode" value="">
		<input type="hidden" name="buyCnt" id="buyCnt" value="">
	</form>
	<input class="btn" type="button" value="선택구매"  onclick="goBuy();" ><!-- 자바스크립트로 가져간다. -->
	<input class="btn" type="button" value="선택삭제" >
</div>
<div>
	<script type="text/javascript" src="js/cart/cart_list.js?ver=023"></script><!-- 자바스크립트 수정할 때마다 변경해줘야 실행가능함 -->
</div>
</body>
</html>
  • cart_list.js
//제목 행의 체크박스의 체크여부를 확인
const allChk = document.querySelector('#allChk');

//제목 줄의 체크박스가 클릭되면..
allChk.addEventListener('click',function(){
	//참고)
	//alert(allChk.checked);
	//allChk.id; //allChk
	//allChk.type;//checkbox

	const isChecked = allChk.checked;//체크된 제목줄 체크박스를 isChecked라고 한다.

	//클래스가 chk 인 태그들을 모두 데리고 온다.
	// 장바구니의 모든 체크박스를 체크한다.
	const chk = document.querySelectorAll('.chk');
	
	//제목 줄의 체크박스가 체크 됐다면..
	if(isChecked){
		//chk.checked = true;
		
		//자바스크립트는 for문사용가능하나 자료형이 없어서 int 사용은 안한다
		for(i = 0; i<chk.length; i++){
			chk[i].checked = true;//체크된 클래스가 chk의 값은 true로 준다.
		}
		
		//자바스크립트의 for-each문: of를 사용한다!
		//for(const e of chk){
		//	e.checked = true;
		//}
	}
	else{
		for(i = 0; i<chk.length; i++){
			chk[i].checked = false;//체크된 클래스가 chk의 값은 true로 준다.
		}
	}
});

//제목줄 아래 체크박스칸들이 전부! 체크가 된다면..
	//제목줄 아래 체크박스칸들이 전부! 가져온다.
	const chk = document.querySelectorAll('.chk');
	
	for(const e of chk){
		//원래라면..
		//매개변수 e
		//e.addEventListener('click',function(e){});
		
		//위의 이벤트문을 조금 변경한다면..
		e.addEventListener('click',e=>{
			const cnt = chk.length; //제목줄 밑의 전체 체크박스의 갯수는 cnt
			const checkedCnt = document.querySelectorAll('.chk:checked').length; //클래스가 chk 인 것들 중에서 체크된것만 들고오겠다.그것의 갯수.
		
		if(cnt == checkedCnt){
			document.querySelector('#allChk').checked = true;
		}
		
		else{
			document.querySelector('#allChk').checked = false;
					
		}		
	});	
}

//선택구매버튼을 클릭하면, '선택한 상품을 구매하시겠습니까?'팝업창을 띄운다.
function goBuy(){
	const checkedCnt = document.querySelectorAll('.chk:Checked').length;//체크박스들중에서 체크된 것들만!(all)그것의 갯수.
	
	if(checkedCnt == 0){
		alert('선택한 상품이 없습니다.');		
		return ;
		//리턴의 2가지 기능
		//1)데이터를 넘기도록 돌려줄 값을 쓸 때(일반적) 
		//2)자바에서는 메소드이기때문에 뒤에 아무값도없으면 더이상 읽지않도록 함수종료 기능.
	}
	
	//장바구니에서 선택한 상품 구매하기 기능 구현
	//넘겨야하는 데이터: 내가 체크한 ITEM_CODE,BUY_CNT,BUY_CODE, //TOTAL_PRICE(상관없어서 넘기지않음)
	//ITEM_CODE, BUY_CNT, totalPrice..
	
	//총가격(장바구니전체):우선,내가 체크된 체크박스와 같은 줄에있는 '총가격(상품별)'만 가져간다. 그리고 그들끼리만 더한다.
	const checkedBoxes = document.querySelectorAll('.chk:checked'); // 여러개가지고 오니까 all 사용
	let totalPrice = 0; // 변하기때문 let 사용한다.
	let itemCodes = ''; // 변하기때문 let 사용한다.
	let buyCnts = ''; // 변하기때문 let 사용한다.
	
	//반복문사용해서 각 체크박스들의 각 총가격을 빼낸다
	for(const checkBox of checkedBoxes){//체크된 checkedBoxes들 중에 하나씩 뺀다 그것을 checkBox 라고한다.
		//자식,부모 태그 선택 함수
		//parentElement() : 가장 가까운 부모태그를 찾아가는 함수
		//children : 가장 가까운 자식태그를 찾아가는 함수
		//previousSibling : 이전 형제 노드를 찾아 감. 제이쿼리는 prev()
		//nextElementSibling() : 다음 형제 노드를 찾아 감. 
		//closest() : 가장 가까운 상위태그를 찾아가는 함수

		//체크박스기준 감싸고있는 것중 가장가까운 tr 태그에서 6번째 자식태그안에 내용
		const price = checkBox.closest('tr').children[5].innerText; 
		totalPrice = totalPrice + parseInt(price); 
			//총가격은 각 총가격에 가격을 누적시킨다.
			//price는 위에서 const자료형이라 숫자합계산이 안되므로 정수형변화시키기!!
		//alert(checkBox.value);

		const itemCode = checkBox.value;
		itemCodes = itemCodes + itemCode +',';//ITEM_001,ITEM_002, 
	
		const buyCnt = checkBox.closest('tr').children[4].innerText; 
		buyCnts = buyCnts + buyCnt +',';
		
		//alert(buyCnt);

		//total = totalPrice * buyCnt;
		//alert(total);
	
	}
	//각각의 빈 value값을 여기서 설정해줘서 빈값이어도 자동으로 개발자모드 콘솔에서 확인 가능하다.
	document.querySelector('#totalPrice').value = totalPrice;
	document.querySelector('#itemCode').value = itemCodes.substr(0,itemCodes.length-1);
	document.querySelector('#buyCnt').value = buyCnts.substr(0,buyCnts.length-1);
	//폼태그 중 액션값이 action="insertBuys.buy" 인 폼태그를 선택해서 submit으로 보내겠다
	document.querySelector('form[action="insertBuys.buy"]').submit();
	//location.href = 'insertBuys.buy?totalPrice=' + totalPrice;// 컨트롤러갈때 총가격을 총가격으로 가져간다
	//totalPrice뿐만아니라 여러 데이터들을 가져가려면 form태그를 사용해서 name값을 가져가는 것이 좋다! 
	
		//항상 마지막 실행하려면 cart_list.jsp 에서 버전 바꾸고 진행하기!!
}
  • buy-mapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="buyMapper">
	<resultMap type="dto.BuyDTO" id="buy">
		<id column="BUY_CODE" 			property="buyCode"/>
		<result column="MEM_ID" 		property="memId"/>
		<result column="BUY_DATE" 		property="buyDate"/>
		<result column="TOTAL_PRICE" 	property="totalPrice"/>
		<association property="cartDTO" resultMap="cart"/>
	</resultMap>
	
	<resultMap type="dto.BuyDetailDTO" id="buyDetail">
		<id column="BUY_DETAIL_CODE" property="buyDetailCode"/>
		<result column="ITEM_CODE" property="itemCode" />
		<result column="BUY_CNT" property="buyCnt" />
		<result column="BUY_CODE" property="buyCode" />
	</resultMap> 
	
	<!-- 구매정보 등록 -->
	<!-- insert 할때 주의!
	     date 처럼 기본적으로 자동값이 있는 경우는 넣지않는다! -->
	<insert id="insertBuy">
		INSERT INTO SHOP_BUY(
			BUY_CODE
			, MEM_ID
			, TOTAL_PRICE
		)VALUES(
			 #{buyCode}
			, #{memId}
			, #{putCnt} * (SELECT ITEM_PRICE  
							FROM SHOP_ITEM
							WHERE ITEM_CODE = #{itemCode})
		)
	</insert>
	
	
	<!-- 구매코드 1씩 증가 -->
	<!--resultType="String" 의 뜻은 디비에서 실제로 쿼리실행했을 때 나오는 결과를 자바로 가져올때는 문자열로 가져오겠다.  -->
	<select id="selectNextBuyCode" resultType="String">
		SELECT 'BUY_'||LPAD(NVL(MAX(TO_NUMBER(SUBSTR(BUY_CODE, 5))), 0) + 1, 3, 0) 
		FROM SHOP_BUY
	</select>
	
	<!-- 구매하기_상세정보 -->
	<!-- '||' 는 문자열 연결이다. -->
	 <insert id="insertBuyDetail" >
	INSERT INTO BUY_DETAIL(
		BUY_DETAIL_CODE
		,ITEM_CODE
		,BUY_CNT
		,BUY_CODE
	) VALUES(
		 #{buyCode}||'_01'
		,#{itemCode}
		,#{buyCnt}
		,#{buyCode}
	)
	</insert> 
	
	<!-- 장바구니에서 구매 등록 -->
	<insert id="insertBuys">
		INSERT INTO SHOP_BUY(
			BUY_CODE
			, MEM_ID
			, TOTAL_PRICE
		)VALUES(
			 #{buyCode}
			, #{memId}
			, #{totalPrice} 
		)
	</insert>
	
	<!-- 장바구니목록에서 선택 구매 -->
	<!--  itemCode,buyCnt는 일단 데이터 받아와야하는 것.-->
	<!-- select는 구매상품의 갯수만큼 반복 -->
	<!-- select할 때마다
	#{buyDetailCode},#{itemCode},#{buyCnt},#{buyCode}의 데이터 한 줄이 담긴 (buyDetailDTO)가 
	여러개 담긴List이기 때문에 컬렉션사용한다 -->
	
	<!--foreach문에서 buyDTO.getbuyDetailList() getter 호출해서 사용하겠다 -->
	<!-- LPAD(#{i}+1,2,0)는 왼쪽부터 시작하는데 i는 0부터시작이라 맨처음 +1하기때문에 사실상 1부터시작하고 2이기때문에 두자릿수이면서 나머지 빈값은 0으로 채운다(왼쪽에) -->
	<insert id="insertBuyDetails">
	INSERT INTO BUY_DETAIL(
		BUY_DETAIL_CODE
		,ITEM_CODE
		,BUY_CNT
		,BUY_CODE
	) 
	<foreach collection="buyDetailList" item="buyDetailDTO" separator="UNION All"  index="i">
		SELECT #{buyDetailDTO.buyDetailCode}||'_'||LPAD(#{i}+1,2,0)
			,#{buyDetailDTO.itemCode}
			,#{buyDetailDTO.buyCnt}
			,#{buyDetailDTO.buyCode} 
		FROM DUAL
	</foreach>
	</insert>
	
</mapper>

-buyService

package service;


import dto.BuyDTO;
import dto.BuyDetailDTO;


public interface BuyService {
	
	//구매정보등록
	void insertBuy(BuyDTO buyDTO,BuyDetailDTO buyDetailDTO);
	
	//다음에 들어갈 구매코드 조회
	String  selectNextBuyCode();
	
	//구매상세정보 
	//구매정보등록에 한꺼번에 작성해야한다. 그래서 따로 작성 x
	//왜? 트랜잭션처리위해서(insert이기때문)
	
	//장바구니 상품 등록
	void insertBuys(BuyDTO buyDTO);
	
	//장바구니목록페이지에서 선택 구매
	//는 위의 상품등록 서비스에서 한꺼번에 등록한다(트랜잭션처리때문)

}

-buyServiceImpl

package service;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import dto.BuyDTO;
import dto.BuyDetailDTO;
import sqlmap.SqlSessionManager;

public class BuyServiceImpl implements BuyService{
	SqlSessionFactory sqlSessionFactory = SqlSessionManager.getSqlSession();
	SqlSession sqlSession = sqlSessionFactory.openSession();
	
	//구매정보등록
	@Override
	public void insertBuy(BuyDTO buyDTO,BuyDetailDTO buyDetailDTO) {
		try {
			sqlSession.insert("buyMapper.insertBuy",buyDTO);
			//트랜잭션 처리는 하나의 메소드 안에 두개 동시에 처리하도록 연달아 작성한다
			//구매상세정보 등록
			sqlSession.insert("buyMapper.insertBuyDetail",buyDetailDTO);
			sqlSession.commit();
		} catch (Exception e) {
			sqlSession.rollback();
			e.printStackTrace();
			
		}
	}
	
	//다음에 들어갈 구매코드 1씩 증가
	@Override
	public String selectNextBuyCode() {
		String nextBuyCode = sqlSession.selectOne("buyMapper.selectNextBuyCode");
		sqlSession.commit();
		return nextBuyCode;
	}
	//장바구니목록에서 선택 구매
	@Override
	public void insertBuys(BuyDTO buyDTO) {
		sqlSession.insert("buyMapper.insertBuys",buyDTO);
		sqlSession.insert("buyMapper.insertBuyDetails",buyDTO);
		sqlSession.commit();
	}
	
}
  • buyDTO (리스트 변수 추가)
package dto;

import java.util.List;

public class BuyDTO {
	
	private String buyCode;
	private String memId;
	private String buyDate;
	private int totalPrice;
	private int putCnt;
	private String itemCode;
	private List<BuyDetailDTO> buyDetailList;
	
	
	public List<BuyDetailDTO> getBuyDetailList() {
		return buyDetailList;
	}
	public void setBuyDetailList(List<BuyDetailDTO> buyDetailList) {
		this.buyDetailList = buyDetailList;
	}
	public int getPutCnt() {
		return putCnt;
	}
	public void setPutCnt(int putCnt) {
		this.putCnt = putCnt;
	}
	public String getItemCode() {
		return itemCode;
	}
	public void setItemCode(String itemCode) {
		this.itemCode = itemCode;
	}
	
	public String getBuyCode() {
		return buyCode;
	}
	public void setBuyCode(String buyCode) {
		this.buyCode = buyCode;
	}
	public String getMemId() {
		return memId;
	}
	public void setMemId(String memId) {
		this.memId = memId;
	}
	public String getBuyDate() {
		return buyDate;
	}
	public void setBuyDate(String buyDate) {
		this.buyDate = buyDate;
	}
	public int getTotalPrice() {
		return totalPrice;
	}
	public void setTotalPrice(int totalPrice) {
		this.totalPrice = totalPrice;
	}
	@Override
	public String toString() {
		return "BuyDTO [buyCode=" + buyCode + ", memId=" + memId + ", buyDate=" + buyDate + ", totalPrice=" + totalPrice
				+ ", buyDetailDTO="  + "]";
	}
	
	
}
  • buyController
package controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;

import dto.BuyDTO;
import dto.BuyDetailDTO;
import dto.CartDTO;
import dto.CartViewDTO;
import dto.CategoryDTO;
import dto.ImgDTO;
import dto.ItemDTO;
import dto.ItemViewDTO;
import dto.MemberDTO;
import service.BuyService;
import service.BuyServiceImpl;
import service.CartService;
import service.ItemService;
import service.ItemServiceImpl;
import service.MemberService;
import service.MemberServiceImpl;
import service.CartServiceImpl;

@WebServlet("*.buy")
public class BuyController extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private BuyService buyService = new BuyServiceImpl();
    public BuyController() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doProcess(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doProcess(request, response);
	}
	
	protected void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//한글 인코딩 처리
		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html;charset=UTF-8");
	
		String requestURI = request.getRequestURI();
		String contextPath = request.getContextPath();
		String command = requestURI.substring(contextPath.length());
		System.out.println("command = " + command);
		
		String page = "jsp/template/template.jsp";
		boolean isRediect = false;
		String contentPage = "";
		
		//구매정보 insert
		if(command.equals("/insertBuy.buy")) {
			String itemCode = request.getParameter("itemCode");
			int putCnt = Integer.parseInt(request.getParameter("putCnt"));
			
			//다음에 들어갈 BUY_CODE 조회
			String buyCode = buyService.selectNextBuyCode();
			
			HttpSession session = request.getSession();
			MemberDTO loginInfo = (MemberDTO)session.getAttribute("loginInfo");
			String memId = loginInfo.getMemId();

			BuyDTO buyDTO = new BuyDTO();
			buyDTO.setItemCode(itemCode);
			buyDTO.setBuyCode(buyCode);
			buyDTO.setPutCnt(putCnt);
			buyDTO.setMemId(memId);
			
			BuyDetailDTO buyDetailDTO = new BuyDetailDTO();
			buyDetailDTO.setBuyCode(buyCode);
			buyDetailDTO.setItemCode(itemCode);
			buyDetailDTO.setBuyCnt(putCnt);
			
			//구매 정보 insert
			buyService.insertBuy(buyDTO, buyDetailDTO);
			
//			contentPage = "buy/buy_list.jsp";
			page ="itemList.it";
			isRediect = false;
		}
		
		//장바구니 목록에서 선택 구매
		else if(command.equals("/insertBuys.buy")) {
			//쿼리먼저만들어야 작성가능!(맵퍼&자바스크립트)
			int totalPrice  = Integer.parseInt(request.getParameter("totalPrice")); 
			String itemCodes = request.getParameter("itemCode");
			String buyCnts = request.getParameter("buyCnt");
			
			//각 배열만다 들어오는 값들을 ','로 나누어서 데이터로 받는다.
			//예)item_001,item_004,item_005
			String[] itemCodeArr =  itemCodes.split(",");
			String[] buyCntArrString= buyCnts.split(",");
			//위에 buyCntArr은 문자열 배열이기 때문에 정수형으로 변환하기
			int[] buyCntArr = new int[buyCntArrString.length];
			
			for(int i = 0 ; i < buyCntArr.length ; i++) {
				buyCntArr[i] = Integer.parseInt(buyCntArrString[i]);
			}
			
			
			//buycode는 미리 만들어둔 1씩증가하는 메소드 사용해서 만들어준다.ㅣ
			String buyCode = buyService.selectNextBuyCode();

			HttpSession session = request.getSession();
			MemberDTO loginInfo = (MemberDTO)session.getAttribute("loginInfo");
			 
			BuyDTO buyDTO = new BuyDTO();
			buyDTO.setTotalPrice(totalPrice);
			buyDTO.setBuyCode(buyCode);
			buyDTO.setMemId(loginInfo.getMemId());
	            //위의 한줄은 밑에 두줄 요약
				//String memId = loginInfo.getMemId();
				//buyDTO.setMemId(memId);
			
			List<BuyDetailDTO> buyDetailList = new ArrayList<>();
			
			for(int i = 0;i<itemCodeArr.length; i++) {//아이템코드배열의 길이는 buyDetailList 리스트길이.그래서 이 길이만큼 반복.
				BuyDetailDTO buyDetailDTO = new BuyDetailDTO();
				buyDetailDTO.setItemCode(itemCodeArr[i]);//각각의 아이템코드배열의 각각의 아이템코드 데이터넣기
				buyDetailDTO.setBuyCnt(buyCntArr[i]);//!!!문자열배열을 정수형으로 변환시켜주기!!!
				buyDetailDTO.setBuyCode(buyCode);
				buyDetailDTO.setBuyDetailCode(buyCode);
				
				buyDetailList.add(buyDetailDTO);
			}

			//미리 buyDTO 안에 리스트 변수 선언하고 getter,setter만들어서 지금 사용!
			buyDTO.setBuyDetailList(buyDetailList);
			
			buyService.insertBuys(buyDTO);
			
			
			
//			contentPage = "buy/buy_list.jsp";
		}
		
//		//구매내역
//		else if (command.equals("/buyList.buy")) {
//			contentPage = "buy/buy_list.jsp";
//		}
		
		request.setAttribute("contentPage", contentPage);
		
		if(isRediect) {
			response.sendRedirect(page);
		}
		else {
			RequestDispatcher dispatcher = request.getRequestDispatcher(page);
			dispatcher.forward(request, response);
		}
	}

}
  • DB에서 기존 테이블 delete 후 프로젝트 실행 후,
    장바구니 구매하기 클릭 후 데이터베이스에서 테이블 조회하여 데이터등록 확인

--6. 구매정보 테이블

    BUY_CODE VARCHAR2(50) PRIMARY KEY -- EX) BUY_001
    , MEM_ID VARCHAR2(100) REFERENCES SHOP_MEMBER (MEM_ID) NOT NULL 
    , BUY_DATE DATE DEFAULT SYSDATE
    , TOTAL_PRICE NUMBER NOT NULL
);

SELECT * FROM SHOP_BUY;
delete SHOP_BUY;

--7. 구매한 사람의 구매상세 테이블
CREATE TABLE BUY_DETAIL(
    BUY_DETAIL_CODE VARCHAR2(100) PRIMARY KEY --EX) BUY_001_01,BUY_001_02,BUY_001_03: 어느 한사람이 3개구매/BUY_002_01,BUY_002_02:다른 사람이 2개구매
    , ITEM_CODE VARCHAR2(50) REFERENCES SHOP_ITEM(ITEM_CODE)
    , BUY_CNT NUMBER NOT NULL
    , BUY_CODE REFERENCES SHOP_BUY(BUY_CODE)
);

SELECT * FROM BUY_DETAIL;
delete BUY_DETAIL;

  • 디비에서 테이블 조회

    • 구매정보테이블 조회

    • 구매상세테이블 조회

profile
Dev.Vinch

0개의 댓글