20220818_thu
GRANT CREATE VIEW TO MYDB;
뷰(view)
: 두 테이블이 마치 하나로 이루어진 것같은 가상테이블(실체X 허상!)
(문제점)select 할 때 빈번한 조인과 서브쿼리의 사용은 프로그램 개발에서 엄청난 피로감을 느낌.
(해결)빈번한 조인,서브쿼리를 한 번만 사용해서 다음부터는 조인 및 서브쿼리를 사용하지 않아도
마치 사용한 것처럼 쿼리의 결과를 조회할 수 있는 기능
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
: 사실 뷰 테이블을 조회해도 사실상 원본 테이블을 조회한 것 이다! 마치 별도로 테이블이 존재한 것 같지만 존재하지 않는다. 민감한 데이터들을 위해서 눈에 안보이게 하기위해 보안상의 이유로 사용된다.
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_NAME
, ITEM_PRICE
, ATTACHED_NAME
FROM ITEM_VIEW
WHERE IS_MAIN = 'Y'
ORDER BY ITEM_CODE DESC;
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;
}
}
<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>
//상품 목록 조회
List<ItemViewDTO> selectItemList();
//상세조회
List<ItemViewDTO> selectDetailItem(String itemCode);
//이미지첨부
@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;
}
<%@ 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)
- '취소' 클릭하면 그냥 아무것도 안한다.
- 장바구니 페이지 구현하기.
- 체크박스/상품이미지/상품명/단가/수량/총 가격/일자 테이블 만들기
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" %>
상품이미지 | 상품명 | 단가 | 수량 | 총 가격 | 등록 일자 | |
${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);
}
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;
}
}
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);
}
}
}
.thdDiv{
border: 1px solid black;
background-color: #C1EFFF;
width: 80%;
margin: 0 auto;
}
.btn{
background-color: #9ED2C6;
border-radius: 3px;
}
상품이미지 | 상품명 | 단가 | 수량 | 총 가격 | 등록 일자 | |
${item.attachedName } | ${item.itemName } | ${item.itemPrice } | ${item.itemStock } | ${item.totalPrice } | ${cart.putDate } |