D+40::쇼핑몰_장바구니 기능 구현/자바스크립트/장바구니_체크박스 자동선택

Am.Vinch·2022년 8월 22일
0

20220822_mon

데이터 조회 후 자바로 데이터를 가져오는 방법

  • 1. 조인,서브쿼리 등을 사용하지 않는 쿼리문(기본-단일 테이블만 조회)
  • 2. 조인,서브쿼리가 포함되는 조회 쿼리문(3가지형태로 코드를 구현 가능)
    -> ex)상품-이미지 테이블 2개이상 테이블 조회..

2. 조인,서브쿼리가 포함되는 조회 쿼리문방식

  • 2-1) 디비 자체기능은 VIEW를 활용하는 방법
  • 2-2) Mybatis를 활용하는 방법(Mybatis의 resultMap을 어떻게 활용할 것인가)
    -> Mybatis은 ServiceImpl에서 sqlSession 사용하는 것..
    • 방법 1)기존 resultMap에 새로운 컬럼을 하나 추가하는 방법
      ex)shop_0810프로젝트_test-mapper.xml 에서..
      <resultMap type="dto.ItemDTO" id="item">
      				<id column="ITEM_CODE" 			property="itemCode"/>
      				<result column="ITEM_NAME" 		property="itemName"/>
      				<result column="ITEM_PRICE" 	property="itemPrice"/>
      			-> 기존 resultMap에 새로운 컬럼을 하나 추가
        				<result column="ATTACHED_NAME" 	property="attachedName"/>
      			</resultMap>
        <!-- 상품목록조회 -->
      			<select id="selectItemList" resultMap="item">
      				SELECT ITEM_CODE
      						, ITEM_NAME
      						, ITEM_PRICE
      						, ATTACHED_NAME (-> 원래없던 컬럼을 조회해야할 때)
      					FROM ITEM
      			</select>
    • 방법 2)테이블 관계에 따라 resultMap에서 association,collection을 추가하는 방법.

DB

  • SHOP.sql

  • test- mapper.xml

    <mapper namespace="testMapper">
    		<resultMap type="dto.PersonDTO" id="person">
    			<id column="JUMIN" 			property="jumin"/>
    			<result column="NAME" 		property="name"/>
    			<result column="AGE" 		property="age"/>
        경력정보는 위의 testMapper의 컬럼들과 다르게 문자열 자료형이 아니다! 
        여러 자료형이 담긴 클래스형 자료형이다
    			(1:1)<association property="careerDTO" resultMap="career"/>
        ->컬럼은 없다. property에는 careerDTO라는 이름으로 담아오겠다. 
          (1:N)<collection property="certiList" resultMap="certi"/>
      </resultMap>
    
    조회한 쿼리문에서 
    NAME,AGE 컬럼들은 위에 personDTO에 담아서 온다.
    하지만 그 밖에 없는 컬럼들은 어떻게 가져오는가?
    COMPANY,WORK_DAY 컬럼들은 밑에 있는 careerDTO에 담아서가져온다.
    	<select id="selectList" resultMap="person">
    			SELECT NAME 
    			    , AGE
    			    , COMPANY
    			    , WORK_DAY
        		//사람테이블의 주민번호 조회(조인)
        		, TEST_PERSON.JUMIN
    			FROM TEST_PERSON, TEST_CAREER
    			WHERE TEST_PERSON.JUMIN = TEST_CAREER.JUMIN
    		</select>
    
    <resultMap type="dto.CareerDTO" id="career">
    			<id column="CAREER_NUM" 			property="careerNum"/>
    			<result column="COMPANY" 		property="company"/>
    			<result column="WORK_DAY" 		property="workDay"/>
    			<result column="JUMIN" 		property="jumin"/>
    </resultMap>
    		
    <resultMap type="dto.CertiDTO" id="certi">
    			<id column="CERTI_NUM" 			property="certiNum"/>
    			<result column="CERTI_NAME" 		property="certiName"/>
    			<result column="CERTI_DATE" 		property="certiDate"/>
    			<result column="JUMIN" 		property="jumin"/>
    		</resultMap>
    <select id="selectList" resultMap="person">
    			SELECT NAME 
    			    , AGE
    			    , COMPANY
    			    , WORK_DAY
    			    , TEST_PERSON.JUMIN
    			FROM TEST_PERSON, TEST_CAREER
    			WHERE TEST_PERSON.JUMIN = TEST_CAREER.JUMIN
    		</select>
    		<select id="selectList2" resultMap="person">
    			SELECT NAME 
    			    , AGE 
    			    , CERTI_NAME 
    			    , CERTI_DATE
    			    , TEST_PERSON.JUMIN
    			FROM TEST_PERSON,CERTI
    			WHERE TEST_PERSON.JUMIN = CERTI.JUMIN
    		</select>
``` > (이해하기위한 설명 참고) ``` PersonDTO - jumin=11111 - name=김자바 - age=20 -careerDTO[ - careerNum=null - company=삼성 - workDay=1년2개월 - jumin=1111 ] - 데이터 값을 빼올 때 PersonDTO.getJumin(); -> 1111 PersonDTO.getCareerDTO().getCompany(); ->삼성 ``` - PersonDTO ``` package dto; import java.util.List; public class PersonDTO { private String jumin; private String name; private int age; private CareerDTO careerDTO;//사람 한명은 경력정보를 하나만 갖을 수 있다->DTO private List certiList;//사람 한 명에 자격증은 여러개 ->List ```
  • PersonDTO 를 이해를 위해 그림으로 그린다면?
    • DB 쿼리문 조회할 때
    • 만약 어느 한사람이 자격증을 3개 가지고있다면? ( 위의 쿼리 조회 결과 중 '김자바'의 경우)
      PersonDTO
      -jumin (111)
      -name (김자바)
      -age (20)
      -certiList(
      certiDTO(certiName[정처기],certiDate[2020년5월],...)
      ,certiDTO(certiName[정처기],certiDate[2020년6월],...)
      ,certiDTO(certiName[정처기],certiDate[2020년7월],...)
      )
  • Q.여기서 이 사람의 이름 값을 가져오고 싶다면?
    personDTO.getName(); -> '김자바'
    • 하지만, 주의 할 점!
      Q. 첫번째 자격증의 취득날짜 데이터값을 가져오고 싶다면?
      personDTO.getCertiList().getCertiDate(); -> X
      personDTO.getCertiList().get(0).getCerciDate(); -> o
    • 뷰가 아닌 이 방법들을 사용하는 이유?
      PersonDTO 하나만 있으면 조회된 데이터 모두 가져와서 사용할 수 있기 때문에

실습내용

  • 장바구니 기능에서 같은 상품끼리는 묶고 수량까지 합하여 장바구니목록페이지에 구현하기
  • CartController.java
@WebServlet("*.ca")
public class CartController extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private CartService cartService = new CartServiceImpl();
    public CartController() {
        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 = "";
		//장바구니 상품등록 
		if(command.equals("/insertCart.ca")) {
			String itemCode = request.getParameter("itemCode");
			int putCnt = Integer.parseInt(request.getParameter("putCnt"));
			//로그인한 회원의 장바구니를 가져온다.(세션사용)
			HttpSession session = request.getSession();
			MemberDTO loginInfo = (MemberDTO)session.getAttribute("loginInfo");
			String memId = loginInfo.getMemId();
			CartDTO cartDTO = new CartDTO();
			cartDTO.setPutCnt(putCnt);
			cartDTO.setItemCode(itemCode);
			cartDTO.setMemId(memId);
			cartService.insertCart(cartDTO);
			page = "jsp/cart/cart_result.jsp";
		}
		//장바구니 목록 페이지 
		else if(command.equals("/cartList.ca")) {
			HttpSession session = request.getSession();
			MemberDTO loginInfo = (MemberDTO)session.getAttribute("loginInfo");
			List<CartDTO> cartList= cartService.selectCartList(loginInfo.getMemId());
			request.setAttribute("cartList", cartList);
			contentPage = "cart/cart_list.jsp";
		}
		request.setAttribute("contentPage", contentPage);
		if(isRediect) {
			response.sendRedirect(page);
		}
		else {
			RequestDispatcher dispatcher = request.getRequestDispatcher(page);
			dispatcher.forward(request, response);
		}
	}
}
  • cart_list.jsp
  </head>
<body>
<table>
	<thead>
		<tr>
			<td><input type="checkbox"></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" ></td>
				<td>
					<!-- cart-mapper 페이지를 보고 판단하고 작성하기!!! -->
						<img width="200px" height="260px" src="images/${cart.imgDTO.attachedName}">
				</td>
					<!-- cart-mapper 페이지를 보고 판단하고 작성하기!!! -->
				<td>${cart.itemDTO.itemName }</td>
				<td>${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 type="button" value="구매하기" onclick="location.href='';">
	<input type="button" value="뒤로가기" onclick="history.go(-1)">
</div>

</body>
</html>
  1. 디비
    장바구니등록할때 같은 상품끼리 병합하는 쿼리문 작성하기
    --병합하기
    MERGE INTO SHOP_CART
    USING DUAL --암기
    ON (ITEM_CODE = 'ITEM_005' 
    AND MEM_ID = 'abc')--두개가 모두 일치해야한다.
    WHEN MATCHED THEN--조건검사가 일치한다면 실행될 쿼리
       UPDATE --테이블명 같이 x
       SET
       PUT_CNT = PUT_CNT + 1 --기존에 들어온 값 + 새로 들어온 값 
       ,TOTAL_PRICE =   --수량 *단가
       WHERE ITEM_CODE  = ?
       AND MEM_ID = ?
    WHEN NOT MATCHED THEN--조건검사가 불일치 했을 때 실행될 쿼리
    INSERT   (
    			CART_CODE
    			,ITEM_CODE
    			,MEM_ID
    			,PUT_CNT
    			,TOTAL_PRICE
    		) VALUES (
    			(SELECT 'CART_'||LPAD(NVL(MAX(TO_NUMBER(SUBSTR(CART_CODE, 6))), 0) + 1, 3, 0) FROM SHOP_CART) 
    			, ?
    			, ?
    			, ?
    			, ? * (SELECT ITEM_PRICE
    							FROM SHOP_ITEM
    							WHERE ITEM_CODE =?)			
    		);
           
           delete from shop_cart; -> 장바구니 테이블 내 데이터 삭제후 다시 실행해야함!
    1. cart-mapper 가서 장바구니 등록 쿼리문 수정
	<!-- 장바구니 등록 -->
	<!-- 서브쿼리사용해서 총 가격 값 구한다 -->
	<!-- (수정) 
	     장바구니에서 같은 상품끼리는 병합 -->
	<insert id="insertCart">
		MERGE INTO SHOP_CART
		USING DUAL
		ON (ITEM_CODE = #{itemCode} AND MEM_ID = #{memId})
		WHEN MATCHED THEN
		    UPDATE 
		    SET
		    PUT_CNT = PUT_CNT + #{putCnt} 
		    ,TOTAL_PRICE = (PUT_CNT + #{putCnt}) * (SELECT ITEM_PRICE FROM SHOP_ITEM WHERE ITEM_CODE = #{itemCode}) 
		  
		    WHERE ITEM_CODE  = #{itemCode}
		    AND MEM_ID = #{memId}
		WHEN NOT MATCHED THEN
		INSERT  (
			CART_CODE
			,ITEM_CODE
			,MEM_ID
			,PUT_CNT
			,TOTAL_PRICE
		) VALUES (
			(SELECT 'CART_'||LPAD(NVL(MAX(TO_NUMBER(SUBSTR(CART_CODE, 6))), 0) + 1, 3, 0) FROM SHOP_CART) 
			, #{itemCode}
			, #{memId}
			, #{putCnt}
			, #{putCnt} * (SELECT ITEM_PRICE
							FROM SHOP_ITEM
							WHERE ITEM_CODE = #{itemCode})			
		)
	</insert>
    1. CartService ,CartServiceImpl
      : 장바구니 등록
      void insertCart(CartDTO cartDTO);
      !!!수정할 필요 없다!
      왜? putCnt,memID,itemCode 모두 cartDTO에 들어있음.
    1. 프로젝트 실행 후, 로그인 후 장바구니 등록하면 처음부터 모두 병합되어 등록된다.

실습내용

  • 총 가격을 처음부터 ITEM_PRICE 를 VARCHAR2로 만들어서 99,999 있지만,
    우리는 int 정수값으로 선언했기때문에 원래 만든 장바구니목록 페이지에서 구현하도록 해본다.
    1. format lib태그 사용하기
      <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>

    1. 상품단가/총 가격 ','표시로 나오도록 format태그 사용해서 만들기
      <td><fmt:formatNumber pattern="₩#,##0" value="${cart.itemDTO.itemPrice }"/> </td>
      <td><fmt:formatNumber pattern="₩#,#00" value="${cart.totalPrice }"/> </td>

  • 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: 1px solid black;
	border-collapse: collapse;
	background-color: #FFFDE3;
	margin: 0 auto;
	text-align: center;
}
tr,td{
border: 1px solid black;
	border-collapse: collapse;
	background-color: #FFD39A;
	margin: 0 auto;
	text-align: center;
}
table > tr:first-child {
	background-color: #FFFDE3;
}
.btns{
	width: 100%;
	margin-top: 20px;
	
}
input([type="button"]){
	height: 40px;
	width: 150px;
	font-size: 25px;
	background-color: #B1D7B4;
	border-color: #B1D7B4;
	color: #224B0C;
}

</style>
</head>
<body>
<table>
	<thead>
		<tr>
			<td><input type="checkbox"></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" ></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><fmt:formatNumber pattern="₩#,#00" value="${cart.totalPrice }"/> </td>
				<td>${cart.putDate }</td>
			</tr>
		 </c:forEach> 
	</tbody>
</table>
<div class="btns" align="center">
	<input type="button" value="구매하기" onclick="location.href='';">
	<input type="button" value="뒤로가기" onclick="history.go(-1)">
</div>

</body>
</html>

자바스크립트_체크박스

실습내용

  • 메뉴판 체크박스를 체크할 때, 자동으로 전체 체크하도록 체크박스 기능 구현하기.
  • 체크박스 태그 선택하기
  • 자바스크립트 cart_list.js 파일 생성
  • 기본적인 상태가 체크 상태이도록 checked 속성의 값을 'checked'으로 부여
  • 먼저 제목줄 체크박스는 cart_list.jsp 에서 id 값 부여하기
    <td><input type="checkbox" id="allChk" checked></td>
  • 제목줄 아래 체크박스는 cart_list.jsp 에서 class 속성 값 부여하기
    <td><input type="checkbox" class="chk" checked></td>
    -> 똑같은 값이 반복되면 if문안의 값들은 id 속성 안되고 class 속성으로 만들어야한다.
  • 그리고 cart_list.js가서 id값,class값으로 태그 선택하기.
    const allChk = document.querySelector('#allChk');

제목줄 체크박스를 선택 할 시, 아래 장바구니 체크박스 모두 자동선택

  • 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로 준다.
		}
	}
});

실습내용

  • 장바구니 목록페이지에서 제목줄 아래에 있는 체크박스가 전부 체크가 되면 제목 체크박스가 체크되도록 기능 구현하기
  • hint
    -> 아래에 있는 전체 체크박스의 수
    -> 아래에 있는 전체 체크박스 중 체크된 수

제목줄 아래 체크박스 전부 선택시, 제목줄 체크박스 자동 선택

  • cart_list.js
//제목줄 아래 체크박스칸들이 전부! 체크가 된다면..
	//제목줄 아래 체크박스칸들이 전부! 가져온다.
	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;
					
		}		
	});	
}
profile
Dev.Vinch

0개의 댓글