D+78::SHOP_선택구매 실제 등록/구매한 상품은 장바구니에서 삭제하기/파이썬-함수_심화/딕셔너리

Am.Vinch·2022년 10월 19일
0

20221019_wed

선택구매

어제 내용 정리
선택구매 DB insert시키기

  • 먼저, BUY-MAPPER에서 쿼리문작성을 해야한다.
    : sop_buy 테이블과 shop_buy_detail 테이블에도 동시에 구매정보 데이터가 들어가야한다.
    둘 다 공통적으로 buy_code가 있다. 그래서 insert하기전에 다음에 들어갈 buy_code값을 조회해서 두 테이블에 넣어줘야하는 것을 알아야한다.
  • mapper에서 buy테이블 insert쿼리문과 buy_deatil테이블 insert쿼리문을 작성한 뒤, 다음buyCode를 조회하는 nextCode쿼리문도 작성한다.
  • service,serviceImpl까지 모두 작성 후, controller에서 이동경로 만들어준다.
    : controller에서 이전에 만들어놓은 쿼리문들을 가져와 사용한다.
  • cartCode 컬럼을 구매할 상품목록조회 쿼리문에 추가해서 조회해준다.

mapper

  • 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="Kh.study.shop.buy.vo.BuyVO" id="buy">
		<id column="BUY_CODE" 	property="buyCode"/>
		<result column="MEMBER_ID" property="memberId"/>
		<result column="BUY_DATE" property="buyDate"/>
		<result column="TOTAL_PRICE" property="totalPrice"/>
		<association property="cartVO" resultMap="cart"/>
	</resultMap>

	<resultMap type="Kh.study.shop.buy.vo.BuyDetailVO" id="buyDetail">
		<id column="BUY_DETAIL_CODE" 	property="buyDetailCode"/>
		<result column="ITEM_CODE" property="itemCode"/>
		<result column="BUY_CODE" property="buyCode"/>
		<result column="BUY_AMOUNT" property="buy_amount"/>
	</resultMap>
	
	<!-- buy_infohtml 뿌려줄 구매'할' 장바구니목록조회 -->
		<!-- 방법1) 서브쿼리 사용 -->
		<!--  장바구니에 들어있는 아이템코드와 똑같은것만 itemName 조회하겠다.-->
		<!-- 장바구니테이블에서 조회된 아이템코드와 같은 것일때의 상품명을 조회하겠다! -->
		<!-- 실제로 내장바구니에서 선택한 것들만 들고와야한다! 그럴땐 조건절에 cartCode를 가져와야한다!! -->
		<!-- ->위에서처럼 그럴땐, IN연산자를 사용해야한다!!! -->
		<select id="selecteBuyingList" resultMap="cartMapper.cart"><!-- 기존에 있던 cart매퍼를 사용한다. -->
		SELECT ITEM_CODE 
				,(SELECT ITEM_NAME 
					FROM SHOP_ITEM 
					WHERE ITEM_CODE = c.ITEM_CODE) AS ITEM_NAME
				,(SELECT ITEM_PRICE 
					FROM SHOP_ITEM 
					WHERE ITEM_CODE = c.ITEM_CODE) AS ITEM_PRICE
				, CART_AMOUNT
				,(SELECT ATTACHED_NAME 
					FROM ITEM_IMG 
					WHERE ITEM_CODE = c.ITEM_CODE
					AND IS_MAIN ='Y') AS ATTACHED_NAME
				, CART_CODE
		FROM SHOP_CART C
		WHERE CART_CODE IN
 		 <foreach collection="cartCodeList" item="cartCode" separator="," open="(" close=")" > 
			#{cartCode}
		 </foreach> 
		</select>
		
		<!-- 방법2) 조인사용 -->
		<!-- <select id="">
		SELECT SHOP_ITEM.ITEM_CODE,ATTACHED_NAME,ITEM_NAME,ITEM_PRICE,CART_AMOUNT
		FROM ITEM_IMG,SHOP_ITEM,SHOP_CART
		WHERE ITEM_IMG.ITEM_CODE = SHOP_ITEM.ITEM_CODE
		AND IS_MAIN ='Y'
		AND SHOP_ITEM.ITEM_CODE = SHOP_CART.ITEM_CODE 여기까지는 모든 장바구니 목록조회
		AND cart_code in ('cart_001','cart_002') 
		</select> -->
	
	
	
	<!-- 구매!!정보!! 등록 -->
	<!-- totalPrice는 받아도 안받아도 된다. -->
	<insert id="insertBuy">
		INSERT INTO SHOP_BUY(
			BUY_CODE
			, MEMBER_ID
			, TOTAL_PRICE
			<!-- , ITEM_CODE -->
		)VALUES(
			 #{buyCode}
			, #{memberId}
			, #{totalPrice}
			<!-- ,(SELECT CART_AMOUNT  
							FROM SHOP_CART
							WHERE CART_CODE = #{cartCode})
			 * (SELECT ITEM_PRICE  
							FROM SHOP_ITEM
							WHERE ITEM_CODE = #{itemCode}) -->
		)
	</insert>
	
	<!-- 구매코드 1씩 증가 -->
	<!--resultType="String" 의 뜻은 디비에서 실제로 쿼리실행했을 때 나오는 결과(buy_001)를 자바로 가져올때는 문자열로 가져오겠다.  -->
	<!-- LPAD(): 1씩 증가시키는데 세자리로 만들면서 나머지왼쪽부터 공백은 0으로 채우겠다. -->
	<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 SHOP_BUY_DETAIL(
			BUY_DETAIL_CODE
			,ITEM_CODE
			,BUY_CODE
			,BUY_AMOUNT
		) 
		<foreach collection="buyDetailList" item="buyDetailVO" separator="UNION ALL" index="i"><!-- BuyVO에 있는 BuyDetailList 변수를 가져와서 그 하나를하나  buyDetailVO라고 한다.-->
			SELECT #{buyCode}||'_'||LPAD(#{i}+1,2,0)
				, #{buyDetailVO.itemCode} 
				, #{buyCode}<!--이 빈값들을 채우기위해 BuyVO를 가져온다. 그래서 이미 BuyVO에는 buyCode값이 존재하기때문에 이렇게 적을 수 있다.  -->
				, #{buyDetailVO.buyAmount}
			FROM DUAL
		</foreach>
		
	</insert>
	
	
	<!-- 구매를 위한 장바구니 정보 조회 -->
		<!-- cart_code가 'cart_001','cart_002'..일 때 -->
		<!-- 위의 데이터의 총 total_price 조회 -->
	<select id="getCartInfoForBuy" resultMap="cartMapper.cart">
		SELECT ITEM_CODE,CART_AMOUNT,TOTAL_PRICE
		FROM SHOP_CART 
		WHERE CART_CODE IN (
 		 <foreach collection="cartCodeList" item="cartCode" separator="," > 
			#{cartCode}
		 </foreach> 
		)
	</select>
	
	<!-- 장바구니 선택삭제 --><!-- cart-mapper에도 있음! 먼저 만들어놓음 혹시몰라 가져옴... -->
	<!--cartCodeList 에는 CART_001,CART_002,CART_003...이렇게 들어있다-->
	<!-- cartCode는 위에 리스트안에 있는 하나하나 를 말한다. cart_001  -->
	<!-- cartCodeList를 데이터로 가져올 때는 사실 cartVO.getCartCodeList(); getter호출과 같다 -->
	<delete id="deleteCarts">
		DELETE SHOP_CART
		WHERE CART_CODE IN 
 		<foreach collection="cartCodeList" item="cartCode" separator="," open="(" close=")" >
			#{cartCode}
		</foreach>
	</delete>
</mapper> 

service

package Kh.study.shop.buy.service;

import java.util.List;

import Kh.study.shop.buy.vo.BuyVO;
import Kh.study.shop.cart.vo.CartVO;

public interface BuyService {
	//구매할 목록조회
	List<CartVO> selecteBuyingList(CartVO cartVO);
	String selectNextBuyCode();
	//구매등록
	void insertBuy(BuyVO buyVO);
	//구매를 위한 장바구니 정보 조회
	List<CartVO> getCartInfoForBuy(CartVO cartVO);
}

serviceImpl

package Kh.study.shop.buy.service;

import java.util.List;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import Kh.study.shop.buy.vo.BuyVO;
import Kh.study.shop.cart.vo.CartVO;

@Service("buyService")
public class BuyServiceImpl implements BuyService{
	@Autowired
	private SqlSessionTemplate sqlSession;
	
	//구매등록(+ 구매상세정보 같이 트랜잭션 처리해야한다)
	@Transactional(rollbackFor = Exception.class)//어떤 오류든 간에 뭐든지 롤백하겠다.
	@Override
	public void insertBuy(BuyVO buyVO) {
		sqlSession.insert("buyMapper.insertBuy",buyVO);
		sqlSession.insert("buyMapper.insertBuyDetail",buyVO);
	}
	
	@Override
	public String selectNextBuyCode() {
		return sqlSession.selectOne("buyMapper.selectNextBuyCode");
	}
	//구매할 장바구니목록조회
	@Override
	public List<CartVO> selecteBuyingList(CartVO cartVO) {
		return sqlSession.selectList("buyMapper.selecteBuyingList",cartVO);
	}
	//구매위한 장바구니정보조회
	@Override
	public List<CartVO> getCartInfoForBuy(CartVO cartVO) {
		return sqlSession.selectList("buyMapper.getCartInfoForBuy",cartVO);
	}

}

controller

package Kh.study.shop.buy.controller;
@Controller
@RequestMapping("/buy")
public class BuyController {
	@Resource(name = "cartService")
	private CartService cartService;
	@Resource(name = "buyService")
	private BuyService buyService;
	@Resource(name = "memberService")
	private MemberService memberService;
	
	// 선택구매
	@RequestMapping("/buyInfo")
	public String buyInfo(Model model,String cartCodes,CartVO cartVO,Authentication authentication) {
		String[] cartCodeArr = cartCodes.split(",");// 위처럼 넘어오는 cartCodes를 쉼표',' 로 분리한다. 그럼 문자열이 여러개나와서 배열로 받아야한다.
		List<String> cartCodeList= Arrays.asList(cartCodeArr);
		cartVO.setCartCodeList(cartCodeList);
		model.addAttribute("buyingList",buyService.selecteBuyingList(cartVO));//구매할 목록조회
		//중요! memberId값은 항상 String memberId가 아니라 Authentication authentication 로 가져와야한다!!!
		User user = (User)authentication.getPrincipal();
		model.addAttribute("memberVO",memberService.selectMemberInfo(user.getUsername()));//구매자정보조회
		
		// 전체 총 가격 데이터 (리스트에서 뽑아서 누적합으로 데이터 던져주기)
			int finalPrice = 0;
			for(CartVO e : cartService.selectCartList(user.getUsername())) {
				finalPrice = finalPrice + e.getTotalPrice();
			}
			model.addAttribute("finalPrice",finalPrice);
				
				
		return "content/buy/buy_info";
	}
	
	// 구매등록
	@PostMapping("/insertBuy")
	public String buyCart(String[] cartCodes, BuyVO buyVO,CartVO cartVO,Authentication authentication) {
		//totalPrice,itemCode(들),수량(들) -> 데이터를 가져와야한다.
		// 하지만!! cartCode(들)만 들고오면 위에 데이터들도 따라오게할 수 있다!!!
		// cart테이블에가면 아이템코드 수량, 토탈프라이스 모두 있기때문에 cartCode만 알면 연결되 나머지 데이터들을 들고올 수 있다.
		// cartCode(들)을 들고오는 방법은?

		System.out.println("!@!!!!!!!!!!!!!!!!!!!@@@@" + cartCodes);// 콘솔확인시, CART_004,CART_007 -> 자스를 사용하지않아도 이런 식으로 데이터를 들고온다.
		// 매개변수에서부터 배열 자료형으로 받으면(String[] cartCodes), 굳이 위에처럼 ,쉼표로 문자열을 자를 필요가 없다.
		//for문을 돌려 하나씩빼서 콘솔 출력한다.
		for(String e : cartCodes) {
			System.out.println("@@@@@@@@@@@@@@@@@@@ " + e);
		}
		
		// buy_code 데이터 들고오기 : insert되어야하는 buy_code 조회
		String buyCode = buyService.selectNextBuyCode();
		
		//totalPrice,itemCode(들),cartAmount(들) 데이터는 어떻게 들고오냐
		//위에 알고있는 cartCode를 이용해서 위 데이터를 쿼리문을 통해 가져온다. -> buy-mapper에서 만들어주기.
		// 우리가 들고온 cartCode들을 cartVO에 넣어줘야한다.
		// 이미 cartVo에는 리스트형태로 cartCodeList가 있는데, 이를 배열의 형태로 바꾸어 넣어준다.
		List<String> cartCodeList = Arrays.asList(cartCodes);
		cartVO.setCartCodeList(cartCodeList);
		List<CartVO> cartList = buyService.getCartInfoForBuy(cartVO);
		List<BuyDetailVO> buyDetailList = new ArrayList<>(); //아래 데이터 넣기위해서 미리 통만들기(변수선언)
		//반복해서 itemCode와 amount값,totalPrice값 모두 for문돌려서 하나씩  빼기
		int totalPrice =0;
		for(CartVO cart : cartList) {
			totalPrice = totalPrice + cart.getTotalPrice();
			//아래처럼 만들어준 것을 위에 buydetailList 통에 넣어준다.
			BuyDetailVO vo = new BuyDetailVO();
			vo.setItemCode(cart.getItemCode());
			vo.setBuyAmount(cart.getCartAmount());
			buyDetailList.add(vo);
		}
		
		//memberID 데이터가져오기
		User user = (User)authentication.getPrincipal();
		
		
		// 위에서 부터 가져온 모든 데이터들을 BuyVO에서 setter를 이용해 데이터 넣어주기
		buyVO.setBuyCode(buyCode);
		buyVO.setMemberId(user.getUsername());
		buyVO.setTotalPrice(totalPrice);
		buyVO.setBuyDetailList(buyDetailList);// buyDetailVO 에서 itemCode,cartAmount값 가져오기.
		
		//실제 구매실행 쿼리문
		buyService.insertBuy(buyVO);
		
		return "content/buy/buy_list";
	}
	//구매 목록조회
	/*
	 * @GetMapping("/buyList") public String buyList() { return
	 * "content/buy/buy_list"; }
	 */
}

선택구매 결과

  • 콘솔창 확인
    : buy-mapper에서 작성된 쿼리문 결과 확인.
20221019 12:24:39.574 [http-nio-8081-exec-1] DEBUG j.sqltiming -  com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
1483. SELECT 'BUY_'||LPAD(NVL(MAX(TO_NUMBER(SUBSTR(BUY_CODE, 5))), 0) + 1, 3, 0) 
		FROM SHOP_BUY
 {executed in 1 msec} 
20221019 12:24:39.574 [http-nio-8081-exec-1] INFO j.resultsettable - 
|--------------------------------------------------------------|
|'buy_'||lpad(nvl(max(to_number(substr(buy_code,5))),0)+1,3,0) |
|--------------------------------------------------------------|
|BUY_002                                                       |
|--------------------------------------------------------------|
 
20221019 12:24:39.575 [http-nio-8081-exec-1] DEBUG j.sqltiming -  com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
1483. SELECT ITEM_CODE,CART_AMOUNT,TOTAL_PRICE
		FROM SHOP_CART 
		WHERE CART_CODE IN (

			'CART_004'
		  ,  
			'CART_007'

		)
 {executed in 0 msec} 
20221019 12:24:39.576 [http-nio-8081-exec-1] INFO j.resultsettable - 
|----------|------------|------------|
|item_code |cart_amount |total_price |
|----------|------------|------------|
|ITEM_006  |10          |189000      |
|ITEM_007  |10          |98000       |
|----------|------------|------------|
 
20221019 12:24:39.577 [http-nio-8081-exec-1] DEBUG j.sqltiming -  com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
1483. INSERT INTO SHOP_BUY(
			BUY_CODE
			, MEMBER_ID
			, TOTAL_PRICE

		)VALUES(
			 'BUY_002'
			, 'aaa'
			, 287000

		)
 {executed in 1 msec} 
20221019 12:24:39.579 [http-nio-8081-exec-1] DEBUG j.sqltiming -  com.zaxxer.hikari.pool.ProxyPreparedStatement.execute(ProxyPreparedStatement.java:44)
1483. INSERT INTO SHOP_BUY_DETAIL(
			BUY_DETAIL_CODE
			,ITEM_CODE
			,BUY_CODE
			,BUY_AMOUNT
		) 

			SELECT 'BUY_002'||'_'||LPAD(0+1,2,0)
				, 'ITEM_006' 
				, 'BUY_002'
				, 10
			FROM DUAL
		 UNION ALL 

			SELECT 'BUY_002'||'_'||LPAD(1+1,2,0)
				, 'ITEM_007' 
				, 'BUY_002'
				, 10
			FROM DUAL
 {executed in 1 msec} 
  • 실제 화면 결과
    : 컨트롤러에서 리턴값을 구매하기 버튼클릭시,구매목록페이지로 이동시켰기 때문에 목록은 아직 나타나지않지만 그림만 보이며 디비를 확인하면 INSERT되어있는 것을 확인할 수 있다.

  • DB결과 조회
    : SHOP_BUY테이블과 SHOP_BUY_DETAIL 테이블을 조회시, INSERT된것을 확인 가능하다.


오늘 실습내용

    1. 구매할 상품은 장바구니에서 삭제되어야한다.
    1. 단일 구매
      : 상품상세정보페이지에서 구매버튼 클릭시 바로 구매되도록 만들기.
      : 구매버튼 클릭시, 바로 구매되는 것이 아니라 buyInfo.html페이지로 바로 이동해야한다.
    1. 메뉴 나오기
    1. 주문내역 조회
    1. 매출관리

구매 후 장바구니에서 삭제

  • BuyController

    : 이전 만들어놓은 삭제쿼리문을 컨트롤러에서 불러온다.
    cartService.deleteCarts(cartVO);

	// 구매등록
	@PostMapping("/insertBuy")
	public String buyCart(String[] cartCodes, BuyVO buyVO,CartVO cartVO,Authentication authentication) {
		//totalPrice,itemCode(들),수량(들) -> 데이터를 가져와야한다.
		// 하지만!! cartCode(들)만 들고오면 위에 데이터들도 따라오게할 수 있다!!!
		// cart테이블에가면 아이템코드 수량, 토탈프라이스 모두 있기때문에 cartCode만 알면 연결되 나머지 데이터들을 들고올 수 있다.
		// cartCode(들)을 들고오는 방법은?

		System.out.println("!@!!!!!!!!!!!!!!!!!!!@@@@" + cartCodes);// 콘솔확인시, CART_004,CART_007 -> 자스를 사용하지않아도 이런 식으로 데이터를 들고온다.
		// 매개변수에서부터 배열 자료형으로 받으면(String[] cartCodes), 굳이 위에처럼 ,쉼표로 문자열을 자를 필요가 없다.
		//for문을 돌려 하나씩빼서 콘솔 출력한다.
		for(String e : cartCodes) {
			System.out.println("@@@@@@@@@@@@@@@@@@@ " + e);
		}
		
		// buy_code 데이터 들고오기 : insert되어야하는 buy_code 조회
		String buyCode = buyService.selectNextBuyCode();
		
		//totalPrice,itemCode(들),cartAmount(들) 데이터는 어떻게 들고오냐
		//위에 알고있는 cartCode를 이용해서 위 데이터를 쿼리문을 통해 가져온다. -> buy-mapper에서 만들어주기.
		// 우리가 들고온 cartCode들을 cartVO에 넣어줘야한다.
		// 이미 cartVo에는 리스트형태로 cartCodeList가 있는데, 이를 배열의 형태로 바꾸어 넣어준다.
		List<String> cartCodeList = Arrays.asList(cartCodes);
		cartVO.setCartCodeList(cartCodeList);
		List<CartVO> cartList = buyService.getCartInfoForBuy(cartVO);
		List<BuyDetailVO> buyDetailList = new ArrayList<>(); //아래 데이터 넣기위해서 미리 통만들기(변수선언)
		//반복해서 itemCode와 amount값,totalPrice값 모두 for문돌려서 하나씩  빼기
		int totalPrice =0;
		for(CartVO cart : cartList) {
			totalPrice = totalPrice + cart.getTotalPrice();
			//아래처럼 만들어준 것을 위에 buydetailList 통에 넣어준다.
			BuyDetailVO vo = new BuyDetailVO();
			vo.setItemCode(cart.getItemCode());
			vo.setBuyAmount(cart.getCartAmount());
			buyDetailList.add(vo);
		}
		
		//memberID 데이터가져오기
		User user = (User)authentication.getPrincipal();
		
		
		// 위에서 부터 가져온 모든 데이터들을 BuyVO에서 setter를 이용해 데이터 넣어주기
		buyVO.setBuyCode(buyCode);
		buyVO.setMemberId(user.getUsername());
		buyVO.setTotalPrice(totalPrice);
		buyVO.setBuyDetailList(buyDetailList);// buyDetailVO 에서 itemCode,cartAmount값 가져오기.
		
		//실제 구매실행 쿼리문
		buyService.insertBuy(buyVO);
		//구매한 장바구니는 목록에서 삭제
		cartService.deleteCarts(cartVO);
		
		return "content/buy/buy_list";
	}

1번. 결과

  • 구매하기 버튼 클릭 후, 장바구니 페이지로 돌아가면 구매한 상품은 삭제되었다.
    : DB에서는 cart테이블에서는 delete되었고, shop_buy, shop_buy_detail테이블에는 insert된 것을 확인할 수 있다.


profile
Dev.Vinch

0개의 댓글