• 필자는 매우 간단하게 장바구니 기능을 구현하였다...(우선 기능을 만든다는 생각으로..)
  • 연습하는 프로젝트에 이미지 게시판이 구현되어있지 않아 일반 게시판 글을 장바구니에 넣는 방식으로 구현 하였다.
  • 추후 이미지 게시판을 넣고 다시 구현해 볼 생각이다.

DB

  • BNO =  게시글 번호(FK)   /    ID =  회원 아이디(FK)    / CNO = PK

Mapper(Oracle)

	
	<!-- 장바구니 목록 리스트 -->
	<select id="CartList" parameterType="cartVO" resultMap="cartResult">
		<![CDATA[
			select * from cart
			where id = #{id}
		]]>
	</select>
	
	<!-- 장바구니 목록 추가 -->
	<insert id="InCart" parameterType="cartVO">
		<![CDATA[
			insert into cart(cno, id , bno , creDate)
			values((select nvl(max(cno)+1,0) from cart), #{id} , #{bno} , SYSDATE)
		]]>
	</insert>
	
	<!-- 장바구니 목록 삭제 -->
	<delete id="DeleteCart" parameterType="int">
		<![CDATA[
			delete from cart
			where cno = #{cno}
		]]>
	</delete>
	
	<!-- 장바구니 목록 눌렀는지 체크 -->
	<select id="findCart" resultType="String" parameterType="cartVO">
	    <![CDATA[
		    select decode(count(*), 0, 'false', 'true') from cart
			where bno = #{bno}
			  and id = #{id} 

    	]]>
	</select>
  • 저는 일반 게시글을 장바구니에 추가,삭제  / 장바구니 리스트 이렇게 구현하였다.
  • 장바구니 넣었는지 안넣었는지 체크하는 쿼리에서 decode()함수를 사용해서 0 이면 'true' 이기에 장바구니에 넣어지고 만약 0이 아니면 'false' 이기에 이미 장바구니에 넣은 게시글이다. 
    • decode() 함수를 사용한 이유는 밑에 로직 부분이나 컨트롤러 부분에서 boolean 타입이기에 사용하였다. decode() 가 if~else와 비슷한 기능이기에..
  • 만약 쇼핑몰 처럼 장바구니 기능을 구현을 하려고 한다면 XML파일에서 이미지게시판 테이블에 대한 resultMap을 가져와서 select 쿼리문 하나 만든 후  상품 과 이미지에 대한 테이블을 조인 후 하면 될 듯 싶다..(?)

DAO

	//장바구니 목록 리스트 
	@Override
	public List<CartVO> CartList(CartVO cartVO)throws DataAccessException{
		List<CartVO> CartList = session.selectList("mapper.cart.CartList",cartVO);
		return CartList;
	}
	
	//장바구니 목록 추가
	@Override
	public void InCart(CartVO cartVO)throws DataAccessException{
		session.insert("mapper.cart.InCart",cartVO);
	}
	
	//장바구니 목록 삭제
	@Override
	public void DeleteCart(int cno)throws DataAccessException{
		session.delete("mapper.cart.DeleteCart",cno);
	}
	
	//장바구니 목록에 들어가 있는가?
	@Override
	public boolean findCart(CartVO cartVO)throws DataAccessException{
		String result =  session.selectOne("mapper.cart.findCart",cartVO);
		return Boolean.parseBoolean(result);
	}
  • findCart 코드에서 return 값을 Boolean.parseBoolean(result) .. parseBoolean 메서드를 사용한 이유는 String타입을 boolean 타입으로 변환하기 위해 사용.
  • 파라미터로 문자열을 받아 boolean 타입으로 파싱. 파라미터로 받은 문자열이 'true'인 경우 true 리턴 그 외 false 리턴

Service

	//장바구니 목록 리스트
	@Override
	public Map<String,List> CartList(CartVO cartVO)throws Exception{
		Map<String,List> cartMap = new HashMap<String,List>();
		List<CartVO> CartList = cartDAO.CartList(cartVO);
		 //장바구니에 저장된 것이 없는경우 null반환
        	if(CartList.size() == 0) {
			return null;
		}
        //장바구니 정보를 cartMap에 담아 저장 후 반환
		cartMap.put("CartList",CartList);
		return cartMap;
	}
	
	//장바구니 목록 체크 하였는가?
	@Override
	public boolean findCartGoods(CartVO cartVO) throws Exception{
		 return cartDAO.findCart(cartVO);
		
	}	
	
	//장바구니 목록 추가
	@Override
	public void InCart(CartVO cartVO) throws Exception{
		cartDAO.InCart(cartVO);
	}
	
	//장바구니 목록 삭제
	@Override
	public void DeleteCart(int cno)throws Exception{
		cartDAO.DeleteCart(cno);
	}

 

Controller

	//장바구니 목록 리스트
	@GetMapping("/CartList.do")
	public ModelAndView CartList(HttpServletRequest request)throws Exception{
		String viewName = (String)request.getAttribute("viewName");
		ModelAndView mav = new ModelAndView();
		HttpSession session =  request.getSession();
		
		//로그인 중인 아이디의 세션을 가져와 cartVO에 있는 id에 set함
		MemberVO memberVO = (MemberVO)session.getAttribute("memberVO");
		String id = memberVO.getId();
		cartVO.setId(id);
		
		Map<String,List>cartMap = cartService.CartList(cartVO);
		//장바구니 목록 화면에서 상품 주문 시 사용하기 위한 장바구니 목록을 세션에 저장
		session.setAttribute("cartMap", cartMap);
		
		return mav;
	}
	
	//장바구니 목록 추가
	@PostMapping("/InCart.do")
	public @ResponseBody String InCart(@RequestParam("bno")int bno, HttpServletRequest request)throws Exception{
		HttpSession session = request.getSession();
		memberVO = (MemberVO)session.getAttribute("memberVO");
		String id = memberVO.getId();
		cartVO.setId(id);
		
		cartVO.setBno(bno);
		cartVO.setId(id);
        //찜 목록 추가 전에 해당 게시글에 대해 추가했는지 확인
		boolean isAreadyExisted = cartService.findCartGoods(cartVO);
		logger.info("isAreadyExisted:" + isAreadyExisted);
        //장바구니에 들어가있다면
		if(isAreadyExisted == true) {
			return "already_existed";
		}else {
        //장바구니에 안들어가있으며, 추가하는부분
			cartService.InCart(cartVO);
			return "add_success";
		}
		
	}
	
	//장바구니 목록 제거
	@PostMapping("/DeleteCart.do")
	public ModelAndView DeleteCart(@RequestParam("cno")int cno)throws Exception{
		ModelAndView mav = new ModelAndView();
		cartService.DeleteCart(cno);
		mav.setViewName("redirect:/cart/CartList.do");
		return mav;
	}

JSP

<button class="InCart">장바구니</button>

....

//장바구니(찜 하기) JS
$('.InCart').click(function (bno){
	var bno = ${board.bno};
	var id = '${memberVO.id}';
	
	if(id == ""){
		alert("로그인 후 이용가능합니다.");
	}
	
	$.ajax({
		type : 'post',
		url : '${Path}/cart/InCart.do',
		data : {
			bno : bno
		},
		success:function(data , textStatus){
			if(data.trim() == "add_success"){
				alert("찜 목록에 추가 되었습니다.");
			}else if(data.trim() == 'already_existed'){
				alert("이미 찜 목록에 등록 되어있습니다.");
			}
		},
		error:function(data,textStatus){
			console.log("에러발생:" + data);
		}
	});//end ajax	
});
  • 추가하는 Ajax 코드이다. 게시글 상세보기 jsp에다가 추가를 해주었다.
  • 그리고 버튼을 만들어서 클릭시 장바구니에 추가하게 함.
  • success 부분에서 data.trim() == .. 이 부분은 Controller 부분에서 if~else 부분에서 return 값이다.
<c:set var="CartList"  value="${cartMap.CartList}"  />
.....
<form method='get'>
	<table>
		<tr>
			<td>번호</td>
		</tr>
		
		<c:choose>
			<c:when test="${empty CartList }">
				<tr>
					<td>
						<strong>장바구니에 상품이 없습니다.</strong>
					</td>
				</tr>
			</c:when>
		  <c:otherwise>
		  	 	<c:forEach var="cart" items="${CartList}">
		  	<tr>
		  	 	<td>${cart.bno}</td>
		  	</tr>
		  	<tr>
		  	 <td>
		  	 	<input type=button value="삭제" style='cursor: pointer; border:none;'
					onClick="Delete_Cart(${cart.cno})">
			</td>
		  	</tr>
		  	 	</c:forEach>
		  </c:otherwise>
		</c:choose>
	</table>	
</form>	
<script type="text/javascript">

	function Delete_Cart(cno) {
		var DelConfirm = confirm('삭제 하시겠습니까?');
		
		
		var paramData = {"cno" : cno};

		if(DelConfirm){	
			alert("삭제 되었습니다.");
		}else{
			alert("삭제가 취소 되었습니다.");
			return;
		}

		var form = document.createElement("form");
		form.setAttribute("method", "post");
		form.setAttribute("action", '${Path}/cart/DeleteCart.do');
		
		var cnoInput = document.createElement("input");
		cnoInput.setAttribute("type", "hidden");
		cnoInput.setAttribute("name", "cno");
		cnoInput.setAttribute("value", cno);

		form.appendChild(cnoInput);
		document.body.appendChild(form);
		form.submit();

	}
</script>
  • 이 부분은 장바구니 목록 jsp 이다. 정말 매우 간단하게 구현을 해보았다.
  • <c:set> 태그는 EL에서 사용되어질 수 있는 Bean, Map등에 값을 설정을 하거나, 일반 변수를 생성해서 값을 할당 할 수 있다. CartList를 Map에 담았기에 사용함.
  • 그냥 게시글을 장바구니에 담으면 목록 리스트에 게시글 번호 , 삭제 버튼 부분만 나오게 하였다.
  • 삭제 스크립트도 버튼을 클릭 시 삭제를 하겠냐는 메시창을 한번 띄워주게 하였으며, createElement()함수 사용 하여서 html요소를 반환 하여서 setAttribute() 속성 값을 설정 하였다. cnoInput 부분은 삭제하는 기준인 cno를 속성 값에 추가하였다.
  • 마지막 두줄 부분에 appendChild() 를 사용하여서  ,변수 form(부모)에  cnoInput(자식)의 내용을 결합
  • 그럼 form에 action 부분에다가 cnoInput의 cno 값이 결합이 되어  삭제를 시키기 위해 코드를 짠 것과 같이 동일하게 됨. 즉 Controller , 로직 부분 에 사용한 부분과 동일하게 되어  삭제 버튼 클릭 시 cno 기준으로 하나 하나 삭제 시킬 수 있다.
복사했습니다!