D+38::DB_테이블 뷰 (VIEW) 사용

Am.Vinch·2022년 8월 18일
0

20220818_thu

  • 뷰만들때 주의사항
    : (어제 배운내용 참고)
    시스템파일에 mydb계정에 뷰기능 권한을 부여해야 사용가능하다
    GRANT CREATE VIEW TO MYDB;

뷰(view)
: 두 테이블이 마치 하나로 이루어진 것같은 가상테이블(실체X 허상!)
(문제점)select 할 때 빈번한 조인과 서브쿼리의 사용은 프로그램 개발에서 엄청난 피로감을 느낌.
(해결)빈번한 조인,서브쿼리를 한 번만 사용해서 다음부터는 조인 및 서브쿼리를 사용하지 않아도
마치 사용한 것처럼 쿼리의 결과를 조회할 수 있는 기능

  • 사원의 사번, 이름, 급여, 부서번호, 부서명,부서지역 조회
    CREATE VIEW MY_EMP AS
    SELECT EMPNO,ENAME,SAL,EMP.DEPTNO,DNAME,LOC
    FROM EMP,DEPT
    WHERE EMP.DEPTNO = DEPT.DEPTNO;

select * from MY_EMP;

SELECT *
FROM EMP
WHERE EMPNO <= 1010;

--CREATE VIEW 뷰테이블명 AS
CREATE VIEW EMP1 AS
SELECT EMPNO,ENAME,JOB,DEPTNO
FROM EMP
WHERE EMPNO <= 1010;

SELECT * FROM EMP1;

--EMP1 과 EMP 테이블의 같은 조건이어도 내용이 다르다
SELECT * FROM EMP1
WHERE DEPTNO =20;

SELECT * FROM EMP
WHERE DEPTNO =20;

EMP 테이블에 데이터를 추가했을 때
EMP1과 EMP는 어떻게 변할까?

UPDATE EMP
SET
JOB = '대리'
WHERE EMPNO = 1001;

--조회 결과
SELECT FROM EMP1;

SELECT
FROM EMP;


EMP1 테이블에 데이터를 추가했을 때
EMP1과 EMP는 어떻게 변할까?

UPDATE EMP1
SET
JOB = '대리'
WHERE EMPNO = 1001;

SELECT FROM EMP1;

SELECT
FROM EMP;

VIEW

: 사실 뷰 테이블을 조회해도 사실상 원본 테이블을 조회한 것 이다! 마치 별도로 테이블이 존재한 것 같지만 존재하지 않는다. 민감한 데이터들을 위해서 눈에 안보이게 하기위해 보안상의 이유로 사용된다.


  • 테이블 생성/삭제 공식
    CREATE TABLE 테이블명;
    CREATE VIEW 뷰테이블명;
    DROP TABLE 테이블명;
    DROP VIEW MY_EMP;

Q.그러면 우리는 뷰를 왜 써야하는가?
: 우리는 상품과 관련된 디비 작업을 많이 진행해야한다.
또,상품에 대한 정보들은 3개의 테이블에 분산되어 있기 때문에
매번 번거로운 조인 작을 해야한다. ->문제점이 많다.

  • 상품코드,상품 카테고리코드,상품카테고리명,상품이름,상품가격,상품설명,첨부된 이미지들 이름,이미지코드,이미지의 메인여부 조인을 사용하여 조회하기

  • 만들고 수정하고싶으면
    CREATE OR REPLACE VIEW 테이블명...
    SELECT * FROM ITEM_VIEW;

CREATE OR REPLACE VIEW ITEM_VIEW AS
SELECT SHOP_ITEM.ITEM_CODE
  ,SHOP_ITEM.CATE_CODE
  ,CATE_NAME
  ,ITEM_NAME
  ,ITEM_PRICE
  ,ITEM_COMMENT
  ,IMG_CODE
  ,ATTACHED_NAME
  ,IS_MAIN
FROM ITEM_CATEGORY, SHOP_ITEM, ITEM_IMAGE
WHERE ITEM_CATEGORY.CATE_CODE = SHOP_ITEM.CATE_CODE
AND ITEM_IMAGE.ITEM_CODE= SHOP_ITEM.ITEM_CODE;
  • item-mapper
    :방금 만든 뷰로 사용하기위해 mapper 쿼리문을 변경하기
    , ITEM_NAME
    , ITEM_PRICE
    , ATTACHED_NAME 
FROM ITEM_VIEW
WHERE  IS_MAIN = 'Y'
ORDER BY ITEM_CODE DESC;
  • itemViewDTO
    :view 사용위해서 itemViewDTO 생성한다.
package dto;

public class ItemViewDTO {
	private String itemCode;
	private String cateCode;
	private String cateName;
	private String itemName;
	private String itemPrice;
	private String itemComment;
	private String imgCode;
	private String attachedName;
	private String isMain;
	public String getItemCode() {
		return itemCode;
	}
	public void setItemCode(String itemCode) {
		this.itemCode = itemCode;
	}
	public String getCateCode() {
		return cateCode;
	}
	public void setCateCode(String cateCode) {
		this.cateCode = cateCode;
	}
	public String getCateName() {
		return cateName;
	}
	public void setCateName(String cateName) {
		this.cateName = cateName;
	}
	public String getItemName() {
		return itemName;
	}
	public void setItemName(String itemName) {
		this.itemName = itemName;
	}
	public String getItemPrice() {
		return itemPrice;
	}
	public void setItemPrice(String itemPrice) {
		this.itemPrice = itemPrice;
	}
	public String getItemComment() {
		return itemComment;
	}
	public void setItemComment(String itemComment) {
		this.itemComment = itemComment;
	}
	public String getImgCode() {
		return imgCode;
	}
	public void setImgCode(String imgCode) {
		this.imgCode = imgCode;
	}
	public String getAttachedName() {
		return attachedName;
	}
	public void setAttachedName(String attachedName) {
		this.attachedName = attachedName;
	}
	public String getIsMain() {
		return isMain;
	}
	public void setIsMain(String isMain) {
		this.isMain = isMain;
	}
}
  • item-mapper.xml
<resultMap type="dto.ItemViewDTO" id="itemView">
		<id column="ITEM_CODE" 			property="itemCode"/>
		<result column="CATE_CODE" 		property="cateCode"/>
		<result column="CATE_NAME" 		property="cateName"/>
		<result column="ITEM_NAME" 		property="itemName"/>
		<result column="ITEM_PRICE" 	property="itemPrice"/>
		<result column="ITEM_COMMENT" 	property="itemComment"/>
		<result column="IMG_CODE" 		property="imgCode"/>
		<result column="ATTACHED_NAME" 	property="attachedName"/>
		<result column="IS_MAIN" 		property="isMain"/>
	</resultMap>
    
    <!-- 상품목록조회 -->
	<select id="selectItemList" resultMap="itemView">
		SELECT ITEM.ITEM_CODE
				, ITEM_NAME
				, ITEM_PRICE
				, ATTACHED_NAME 
			FROM ITEM_VIEW
			WHERE  IS_MAIN = 'Y'
			ORDER BY ITEM_CODE DESC
	</select>
    
    <!-- 상품 상세 정보 조회 -->
	<!-- 상세조회이기때문에 첨부된 이미지 모두 들고와야해서 ISMAIN 넣을 필요없다! -->
	<!-- 메인이미지 조회 추가로 넣어줘야한다! -->
	<select id="selectDetailItem" resultMap="itemView">
		SELECT ITEM_CODE
		    , ITEM_NAME
		    , ITEM_COMMENT
		    , ITEM_PRICE
		    , ATTACHED_NAME 
		    , IS_MAIN
		FROM ITEM_VIEW
		WHERE ITEM_CODE = #{itemCode}
	</select>  
  • itemService
//상품 목록 조회
	List<ItemViewDTO> selectItemList();
//상세조회
	List<ItemViewDTO> selectDetailItem(String itemCode);	
  • itemServiceImpl
//이미지첨부
 @Override
	public List<ItemViewDTO> selectItemList() {
		List<ItemViewDTO> list = sqlSession.selectList("itemMapper.selectItemList");
		sqlSession.commit();
		return list;
	}
  
  //상세조회(조회시 여러 이미지들(메인,상세)들고오니까 두 개가뜬다!!! 그래서 > selectList
  @Override
	public List<ItemViewDTO> selectDetailItem(String itemCode) {
		List<ItemViewDTO> result = sqlSession.selectList("itemMapper.selectDetailItem", itemCode);
		sqlSession.commit();
		return result;
	}

상세보기 페이지 구현

  • item_detail.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri= "http://java.sun.com/jsp/jstl/core" %> 	
    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
.detail-container{
	margin: 0 auto;
	width: 80%;
	display: inline-block;
	background-color: #F7ECDE;
	
}
.detail-container > div{
	margin-bottom: 10px;
}
.firstDiv{
	text-align: center;
	padding: 10px;
	border: 1px solid black;
	background-color: #9ED2C6;
}
.firstDiv>div{
	border: 1px solid black;
	display: inline-block;
	width: 40%;
	height: 80%;
}
.firstDiv>div:first-child{
	display: inline-block;
	background-color: gray;
}
.firstDiv>div:last-child{
	display: inline-block;
	background-color: lime;
}
.firstDiv > div:last-child >div{
	border: 1px solid black;
	background-color: #F0F2B6;
	margin: 6px;
	padding: 6px;
}

.secDiv{
	border: 1px solid black;
	background-color: #224B0C;
	width: 80%;
	margin: 0 auto;
}

.thdDiv{
	border: 1px solid black;
	background-color: #C1EFFF;
	width: 80%;
	margin: 0 auto;
}
.btn{
	background-color: #9ED2C6;
	border-radius: 3px;
}



</style>
</head>
<body>
<form action="itemDetail.it" method="post">
	<input type="hidden" value="${item[0].itemCode}">
	
<div class="detail-container">
	<div class="firstDiv">
		<div>Main image
			<c:forEach var="itemView" items="${item}">
				<c:if test="${itemView.isMain eq 'Y' }">
					<img  width="300px" height="360px" src="images/${itemView.attachedName}">
				</c:if>
			</c:forEach>
		</div>
		
		<div>
			<div>Name : 
			<!-- item 은 List이다!!! 그래서 그냥 item. 으로 사용불가능! -->
			${item[0].itemName}</div>
			<div>Price :
			${item[0].itemPrice}</div>
			<div>Stock : 
				<input type="number" class="my-input" name="itemStock"></div>
			<div>Total Price : 
			${item[0].itemPrice * itemStock}</div>
			<div>
				<div class="btnDiv">
					<input type="button" class="btn" value="구매하기" onclick="">
					<input type="button" class="btn" value="장바구니" onclick="">
				</div>
			</div>
		</div>
	</div>
	
	<div class="secDiv">
		<div>itemComment :</div>
		<div>${item[0].itemComment}</div>
	</div>
	<div class="thdDiv">
		<div>Detail.</div>
		<div>
			<c:forEach var="itemView" items="${item}">
				<c:if test="${itemView.isMain eq 'N' }">
					<img src="images/${itemView.attachedName}">
				</c:if>
			</c:forEach>
		</div>
	</div>
</div>	
</form>
</body>
</html>


장바구니 페이지 구현

실습내용

  • 장바구니 버튼 클릭하면 해당 상품이 장바구니에 담기고(INSERT)
  • CONFIRM으로 '장바구니에 상품이 담겼습니다. 장바구니로 이동하시겠습니까?'띄운다.
    • '확인' 클릭하면 장바구니로 이동(jsp/cart/cart_list.jsp)
    • '취소' 클릭하면 그냥 아무것도 안한다.
  • 장바구니 페이지 구현하기.
    • 체크박스/상품이미지/상품명/단가/수량/총 가격/일자 테이블 만들기
  • DB 장바구니 테이블 생성
    • 장바구니 테이블
CREATE TABLE SHOP_CART (
    CART_CODE VARCHAR2(50) PRIMARY KEY -- CART_001
    , ITEM_CODE VARCHAR2(50) REFERENCES SHOP_ITEM (ITEM_CODE) NOT NULL
    , MEM_ID VARCHAR2(100) REFERENCES SHOP_MEMBER (MEM_ID) NOT NULL
    , PUT_DATE DATE DEFAULT SYSDATE
    , PUT_CNT NUMBER NOT NULL
    , TOTAL_PRICE NUMBER NOT NULL
);
  • DB 쿼리 작성
    장바구니 테이블
    CREATE TABLE SHOP_CART (
    CART_CODE VARCHAR2(50) PRIMARY KEY -- CART_001
    , ITEM_CODE VARCHAR2(50) REFERENCES SHOP_ITEM (ITEM_CODE) NOT NULL
    , MEM_ID VARCHAR2(100) REFERENCES SHOP_MEMBER (MEM_ID) NOT NULL
    , PUT_DATE DATE DEFAULT SYSDATE
    , PUT_CNT NUMBER NOT NULL
    , TOTAL_PRICE NUMBER NOT NULL
    );

SELECT * FROM SHOP_CART;

(참고)
--총가격 쿼리 만들 때,
---상품코드가 ITEM_001인 상품의 상품 단가 조회
select item_price
from shop_iTem
where item_code = 'ITEM_001';

INSERT INTO SHOPCART (
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)
, 'cart_001'
, 'abc'
, 1
, 1* (SELECT ITEM_PRICE
FROM SHOP_ITEM
WHERE ITEM_CODE = 'ITEM_001')
);


중요!! 매퍼만들고 나면 항상 매퍼생성한 것을 configuration.xml 에 작성해야한다!!!

  • 1.configuration.xml

    	<!-- mapper.xml 파일 설정 -->
    	<mappers>
    		<mapper resource="sqlmap/member-mapper.xml" />
    		<mapper resource="sqlmap/item-mapper.xml" />
    		<mapper resource="sqlmap/cart-mapper.xml" />
    	</mappers>
  • cart-mapper.xml
    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri= "http://java.sun.com/jsp/jstl/core" %>

    Insert title here
    상품이미지 상품명 단가 수량 총 가격 등록 일자
    ${item.attachedName } ${item.itemName } ${item.itemPrice } ${item.itemStock } ${item.totalPrice } ${cart.putDate }
  • cartService.java
    package service;

import java.util.List;

import dto.CartDTO;

public interface CartService {
//장바구니 등록
void insertCart(CartDTO cartDTO);

//장바구니 목록 조회
List<CartDTO> selectCart(String cartCode);

}

  • cartServiceImpl.java

package service;

import java.util.List;

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

import dto.CartDTO;
import dto.CategoryDTO;
import dto.ImgDTO;
import dto.ItemDTO;
import dto.ItemViewDTO;
import sqlmap.SqlSessionManager;

public class CartServiceImpl implements CartService{
//쿼리 실행하는 객체
SqlSessionFactory sqlSessionFactory = SqlSessionManager.getSqlSession();
SqlSession sqlSession = sqlSessionFactory.openSession();
//장바구니 상품 등록
@Override
public void insertCart(CartDTO cartDTO) {
sqlSession.insert("cartMapper.insertCart",cartDTO);
sqlSession.commit();

}
//장바구니 목록조회
@Override
public List<CartDTO> selectCart(String cartCode) {
	List<CartDTO> cartList = sqlSession.selectList("cartMapper.selectCart",cartCode);
	sqlSession.commit();
	return cartList;
}

}

  • cartController.java
    package controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
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.CartDTO;
import dto.CategoryDTO;
import dto.ImgDTO;
import dto.ItemDTO;
import dto.MemberDTO;
import service.CartService;
import service.ItemService;
import service.ItemServiceImpl;
import service.MemberService;
import service.MemberServiceImpl;
import service.CartServiceImpl;

@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.setMemId(memId);
		cartDTO.setItemCode(itemCode);
		
		cartService.insertCart(cartDTO);
		
		page = "jsp/cart/cart_result.jsp";
	}
	
	//장바구니 목록 페이지 
	else if(command.equals("/cartList.ca")) {
		/*
		 * request.setAttribute("cartList", cartService.selectCart("cartCode")); String
		 * cartCode = request.getParameter("cartCode"); List<CartDTO> cartList =
		 * cartService.selectCart(cartCode); request.setAttribute("cart", 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);
	}
}

}

  • item_detail.jsp
    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri= "http://java.sun.com/jsp/jstl/core" %>
Insert title here

.thdDiv{
border: 1px solid black;
background-color: #C1EFFF;
width: 80%;
margin: 0 auto;
}
.btn{
background-color: #9ED2C6;
border-radius: 3px;
}

Main image
Name : ${item[0].itemName}
Price : ${item[0].itemPrice}
Stock :
Total Price : ${item[0].itemPrice}
itemComment :
${item[0].itemComment}
Detail.
  • cart_result.jsp
    <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%> Insert title here
  • 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" %> Insert title here
    상품이미지 상품명 단가 수량 총 가격 등록 일자
    ${item.attachedName } ${item.itemName } ${item.itemPrice } ${item.itemStock } ${item.totalPrice } ${cart.putDate }
profile
Dev.Vinch

0개의 댓글