보라코딩

Day70_230406_ JSP, MyBatis 방명록, Shop 본문

코딩/Servlet, JSP, MyBatis

Day70_230406_ JSP, MyBatis 방명록, Shop

new 보라 2023. 4. 6. 18:19

최종 방명록 프로젝트 파일(JSP, MyBatis)

 

08_MyBatis_Guestbook.zip
6.44MB

 

 

 

delete.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%-- (실습) 전달받은 데이터를 사용해서 DB데이터 삭제(delete) 후 화면전환
비교값 : 전달받은 pwd 파라미터값과 session의 pwd(DB값) 비교
- 일치하면 : DB 데이터 삭제 후 목록페이지로 이동
- 불일치면 : 이전페이지(삭제화면) 이동 - 암호 재입력 할 수 있도록
삭제성공 : 전체목록 페이지 이동
예외발생 : 상세페이지로 이동
--%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" href="../css/guestbook.css" type="text/css">

<body>
<div id="container">
<h2>방명록 : 삭제화면(delete.jsp)</h2>
<hr>
<p><a href="list.jsp">[목록으로 이동]</a></p>

<form action="delete_ok.jsp" method="post">
<table>
<tbody>
<tr>
<th>비밀번호</th>
<td>
<input type="text" name="pwd">
<input type="submit" value="삭 제" >
</td>
</tr>

</tbody>
</table>
</form>
</div>
</body>
</html>

 

mapper.xml

   <delete id="delete" parameterType="int">
   DELETE FROM GUESTBOOK 
WHERE IDX = #{idx}
   </delete>

 

 

delete_ok.jsp

<%@page import="com.mystudy.mybatis.GuestbookVO"%>
<%@page import="com.mystudy.mybatis.DBService"%>
<%@page import="org.apache.ibatis.session.SqlSession"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%-- (실습) 전달받은 데이터를 사용해서 DB데이터 삭제(delete) 후 화면전환
비교값 : 전달받은 pwd 파라미터값과 session의 pwd(DB값) 비교
- 일치하면 : DB 데이터 삭제 후 목록페이지로 이동
- 불일치면 : 이전페이지(삭제화면) 이동 - 암호 재입력 할 수 있도록
삭제성공 : 전체목록 페이지 이동
예외발생 : 상세페이지로 이동
--%>
<%
//0. 한글처리 encoding 설정
request.setCharacterEncoding("UTF-8");
//1. 파라미터값 확인 후 암호 일치여부 확인
//1-1. 전달받은 파라미터값 확인
String pwd = request.getParameter("pwd");

//1-2. 전달받은 session 데이터(VO) 확인
GuestbookVO vo = (GuestbookVO) session.getAttribute("guestbookVO");
System.out.println("delete_ok의 session : " + vo);

//2. 일치하면 DB연동작업 (삭제-delete)
int result = -999;
if (pwd.equals(vo.getPwd())) {

System.out.println(">> 암호일치");
// DB데이터 삭제처리
//SqlSession ss = DBService.getFactory().openSession(true); //오토커밋 처리
SqlSession ss = DBService.getFactory().openSession(); //오토커밋 해제
try {
// int result = ss.delete("guestbook.delete", vo);
result = ss.delete("guestbook.delete", vo.getIdx());
System.out.println("삭제 건수 : " + result);
ss.commit();
} catch(Exception e) {
ss.rollback();
result = -1;
System.out.println("예외발생 : " + e.getMessage());
e.printStackTrace();
} finally {
ss.close();
}
}

//3. 화면전환(페이지변경)


%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>결과메시지</title>
<script>
let result = <%=result%>;

if (result > 0){ //삭제성공
alert("삭제 성공 " + result + "건 삭제되었습니다. 목록페이로 이동합니다.");
location.href = "list.jsp";
}

if (result == 0){ //삭제실패(데이터가 없음)
alert("데이터 없어서 삭제 실패.  목록페이로 이동합니다.");
location.href = "list.jsp";
}

if (result = -999){ 
alert("암호불일치, 암호 확인 필요");
//history.back();
location.href = "delete.jsp";
}
if (result == -1) {
alert("[예외발생] 문제가 있어 삭제 실패. 담당자 연락하시오")
history.go(-2);
}
</script>
<link rel="stylesheet" href="../css/guestbook.css">
</head>
<body>
</body>
</html>

 


** mapper.xml에서 parametertype 입력하지 않아도 상관없다.

 

 

** 추후 여러개 작업 처리를 하면 명시적으로 commit, rollback 처리를 해줘야한다!

 

 

 

 


 

 

Shop 프로젝트 시작!

 

 

jstl- 1.2.jar

mybatis-3.5.13.jar

ojdbc8.jar

복사하여 lib에 붙여넣기

 

 

DBService.java

config.xml

mapper.xml

은 복붙한 후에

새로운 프로젝트에 알맞게 수정한다.

 

 

 

 

search 이용하면 편리함

 

 

 

 

 

config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="oracle.jdbc.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
        <property name="username" value="mystudy"/>
        <property name="password" value="mystudypw"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="com/mystudy/shop/mapper.xml"/>
  </mappers>
</configuration>

 

 

 

 

DBService.java

package com.mystudy.shop;


import java.io.IOException;
import java.io.Reader;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

// MyBatis 사용해서 작업할 SqlSession 을 만들어줄
// SqlSessionFactory 객체 생성을 위한 클래스
public class DBService {
private static SqlSessionFactory factory;

// static 초기화 구문
static {
try {
String config = "com/mystudy/shop/config.xml";

factory = new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsReader(config));
} catch (IOException e) {
e.printStackTrace();
}
}

public static SqlSessionFactory getFactory() {
return factory;
}
}

 

 

 

shop.jsp (메인페이지)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>쇼핑몰 메인</title>

<link href="css/menu.css" rel="stylesheet" type="text/css">

</head>
<body>

<%@ include file = "common/menu.jspf" %>

</body>
</html>



 

 

 

menu.jspf

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
        
<div id="wrap">
<hr>
<div id="header">
<span class="title">SHOPPING CENTER</span>
</div>
<hr>
<div id="nav">
<a href="product_list.jsp?category=com001">Computer</a> |
<a href="product_list.jsp?category=ele002">Appliances</a> |
<a href="product_list.jsp?category=sp003">Sports</a>

</div>

</div>
     
<div id="wrap">
<hr>
<div id="header">
<span class="title">SHOPPING CENTER</span>
</div>
<hr>
<div id="nav">
<a href="product_list.jsp?category=com001">Computer</a> |
<a href="product_list.jsp?category=ele002">Appliances</a> |
<a href="product_list.jsp?category=sp003">Sports</a>

</div>

</div>

 

 

 

menu.css

@charset "UTF-8";
* { font-family: fantasy; }
#wrap { margin : 0 auto; }
#wrap hr { width: inherit; border : 1px solid pink;}
#header, #nav {
width : 900px;
margin : 10px auto;
text-align : center;
}
#header { font-size : 2em; color : #edacb1; }
#nav { font-size : 1.3em; }
#nav a { text-decoration: none; color : #0099a4; margin : 10px; }
td a { text-decoration: none; color : #0099a4; margin : 10px; }
td a:hover { text-decoration: underline; color : tomato; }
#nav a:hover { text-decoration: underline; color : tomato; }

 

 

 

 

 

 

 

 

 

productVO.java

package co
m.mystudy.shop;

import java.sql.Date;

public class ProductVO {

private int num;
private String category;
private String pnum;
private String name;
private String company;
private int price;
private int saleprice;
private String imageSmall;
private String imageLarge;
private String content;
private Date regdate;

// 수량, 수량별 금액 (판매가 * 수량)
private int quant; //장바구니에 담긴 수량
private int totalPrice; //수량별 금액(판매가 * 수량)


//할인율 조회 메소드
public int getPercent() {
double percent = (price - saleprice)*100/price;
//System.out.println(percent);
return (int)percent;
}


public int getQuant() {
return quant;
}
public void setQuant(int quant) {
this.quant = quant;
// 수량이 변경되면 수량별 금액(totalPrice) 계산 후 변경처리
totalPrice = saleprice * quant;
}
public int getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(int totalPrice) {
this.totalPrice = totalPrice;
}



//DB 데이터 처리 getters, setters
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getPnum() {
return pnum;
}
public void setPnum(String pnum) {
this.pnum = pnum;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getSaleprice() {
return saleprice;
}
public void setSaleprice(int saleprice) {
this.saleprice = saleprice;
}
public String getImageSmall() {
return imageSmall;
}
public void setImageSmall(String imageSmall) {
this.imageSmall = imageSmall;
}
public String getImageLarge() {
return imageLarge;
}
public void setImageLarge(String imageLarge) {
this.imageLarge = imageLarge;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getRegdate() {
return regdate;
}
public void setRegdate(Date regdate) {
this.regdate = regdate;
}

@Override
public String toString() {
return "ProductVO [num=" + num + ", category=" + category + ", pnum=" + pnum + ", name=" + name + ", company="
+ company + ", price=" + price + ", saleprice=" + saleprice + ", imageSmall=" + imageSmall
+ ", imageLarge=" + imageLarge + ", content=" + content + ", regdate=" + regdate + ", quant=" + quant
+ ", totalPrice=" + totalPrice + "]";
}

}

 

 

 

 

product_list.jsp

<%@page import="com.mystudy.shop.ProductVO"%>
<%@page import="java.util.List"%>
<%@page import="com.mystudy.shop.ProductDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

<%-- 전달받은 품목분류코드(category)값에 해당하는 
제품정보를 DB에서 조회하고 화면에 목록형태로 표시(출력) --%>
<jsp:useBean id="dao" class="com.mystudy.shop.ProductDAO"
 scope="session"/>
<%
// 전달받은 파라미터 값 추출
String category = request.getParameter("category");
//ProductDAO dao = new ProductDAO();
//List<ProductVO> list = dao.list(category);

// 화면 출력을 위해 pageScope에 데이터 저장 (EL, JSTL 사용 위해서!!)
pageContext.setAttribute("list", dao.list(category));
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>제품목록</title>

<link href="css/menu.css" rel="stylesheet" type="text/css">
<style>
table {
width : 80%;
margin : 30px auto 0; /* 상 좌우 하 */
border : 1px solid thistle;
border-collapse : collapse;
}
th {
background-color: thistle; color : white;
}
th, td { border : 1px solid thistle; padding : 5px; text-align: center; }
.red {color : red;}

</style>
</head>
<body>

<%@ include file = "common/menu.jspf" %>
<table>
<thead>
<tr>
<th>제품번호</th>
<th>이미지</th>
<th>제품명</th>
<th>제품가격</th>
<th>비고</th>
</tr>
</thead>

<tbody>
<%-- 등록된 제품이 있는 경우 --%>
<c:forEach var="vo" items="${list}">
 <tr>
<td>${vo.pnum}</td>
<td><img src="images/${vo.imageSmall}" width="100px" height="95px"></td>
<td>
<a href="product_content.jsp?pnum=${vo.pnum }">
${vo.name }
</a>
</td>
<td>할인가 : ${vo.saleprice}<br><span class="red">(할인율 : ${vo.getPercent()}%)</span></td>
<td>정가 : ${vo.price}원</td>
 </tr>
</c:forEach>

<%-- 등록된 제품이 없는 경우 --%>
<c:if test="${empty list}">
<tr>
<td colspan="5">제품 준비중 ~</td>
</tr>
</c:if>
</tbody>
</table>

</body>
</html>

 

 

 

 

mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "
https://mybatis.org/dtd/mybatis-3-mapper.dtd
">
<mapper namespace="shop">
<!--  <resultMap id="result_PVO" type="co
m.mystudy.shop.ProductVO
">
<id property="num" column="NUM"/>
<result property="category" column="CATEGORY" />
<result property="pnum" column="PNUM" />
<result property="name" column="NAME" />
<result property="company" column="COMPANY" />
<result property="price" column="PRICE" />
<result property="saleprice" column="SALEPRICE" />
<result property="imageSmall" column="IMAGE_SMALL" />
<result property="imageLarge" column="IMAGE_LARGE" />
<result property="content" column="CONTENT" />
<result property="regdate" column="REGDATE" />
</resultMap> -->

<!-- select 태그 3개 속성 : id, resultType, parameterType 
id : 사용할 명칭(필수항목 / sql 가리킬때), 현재 매퍼에서 유일한 이름 사용
resultType : 조회 결과값 저장하기 위한 데이터 타입(1개에 대한)
parameterType : 전달 받은 파라미터 데이터의 타입 지정(선택적)
-->

<select id="list" resultType="PVO"> 
<!-- parameterType="string"  -->
SELECT NUM, CATEGORY, PNUM, NAME, COMPANY, 
PRICE, SALEPRICE, IMAGE_SMALL, IMAGE_LARGE, CONTENT, 
REGDATE 
FROM PRODUCT 
WHERE CATEGORY = #{category}
</select>

<select id="one" resultType="PVO"> 
<!-- parameterType="string"  -->
SELECT NUM, CATEGORY, PNUM, NAME, COMPANY, 
PRICE, SALEPRICE, IMAGE_SMALL, IMAGE_LARGE, CONTENT, 
REGDATE 
FROM PRODUCT 
WHERE PNUM = #{pnum}
</select>

</mapper>

 

 

 

productDAO.java

package com.mystudy.shop;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

public class ProductDAO {

public ProductDAO() {
System.out.println(">> ProductDAO 객체 생성");
}

public List<ProductVO> list(String category){
SqlSession ss = DBService.getFactory().openSession();
List<ProductVO> list = ss.selectList("shop.list", category);
ss.close();

return list;
}

}

 

 

 

 

 

 

config.xml에 새로운 설정을 추가했는데

SQL에서 _ 사용한 것을 자바에서 CamelCase(낙타표기법)으로 변경해주는 설정이다!

<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="jdbcTypeForNull" value="NULL" />
</settings>

 

 

자바의 null을 DB의 null로 설정!

<typeAliases>
<typeAlias type = "com.mystudy.shop.ProductVO" alias="PVO"/>
</typeAliases>

 

 

 

 

 

 

 

 

 

 

 

product_content.jsp

 

<%@page import="com.mystudy.shop.ProductVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%-- 전달받은 제품번호(pnum)을 사용해서 DB데이터 조회 후 화면 표시 --%>

<%-- useBean 액션태그는 scope상에서 id명으로 저장된 데이터 찾고
있으면 사용하고 없으면 새로 생성한다  --%>
<jsp:useBean id="dao" class="com.mystudy.shop.ProductDAO"
 scope="session"/>
<%
//전달받은 제품번호(pnum) 확인 (파라미터값 추출)
String pnum = request.getParameter("pnum");

//EL, JSTL 사용을 위한 속성값 설정
pageContext.setAttribute("vo", dao.selectOne(pnum));
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>제품상세정보</title>

<link href="css/menu.css" rel="stylesheet" type="text/css">
<link href="css/data_table.css" rel="stylesheet" type="text/css">
</head>
<body>

<%@ include file = "common/menu.jspf" %>

<table>
<tbody>
<tr>
<th class="title">품목코드</th>
<td>${vo.category }</td>
</tr>
<tr>
<th>제품번호</th>
<td>${vo.pnum }</td>
</tr>
<tr>
<th>제품명</th>
<td>${vo.name }</td>
</tr>
<tr>
<th>제조사</th>
<td>${vo.company }</td>
</tr>
<tr>
<th>제품가격</th>
<td>정가 : ${vo.price }<span class="red"> (할인가격 : ${vo.saleprice })</span></td>
</tr>
<tr>
<th>제품설명</th>
<td>${vo.content }</td>
</tr>
<tr>
<td class="center" colspan="2">
<img src="images/${vo.imageLarge}" alt="${vo.name }">
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">
<div>
<button onclick="add()">장바구니 담기</button>
<button onclick="cart_go()">장바구니 보기</button>
</div>
</td>
</tr>

</tfoot>
</table>

<script>
function add(){
location.href = "addProduct.jsp?pnum=${vo.pnum}";
}
function cart_go(){
location.href = "cartList.jsp";
}
</script>
</body>
</html>

 

 

 

data_table.css

table {
width : 80%;
margin : 30px auto 0; /* 상 좌우 하 */
border : 1px solid thistle;
border-collapse : collapse;
}
th {
background-color: thistle; color : white;
}
th, td { border : 1px solid thistle; padding : 5px; }
.red {color : red;}
.title{ width:15%; }
tfoot { height : 3em; text-align:center;}
.center { text-align:center;}

 

 

 

 

 

09_Shop.zip
6.73MB

 

진행중