[JSP] 웹 쇼핑몰 페이지 만들기 (3)

yeju·2023년 6월 27일
0

연습

목록 보기
6/7

📝 Step 13. 데이터베이스와 JSP 연동하기

지금까지 ArrayList 에 저장하던 상품 목록을 데이터베이스에 저장하고, 데이터베이스를 JSP와 연동해 상품 목록을 가져오도록 수정한다.
데이터베이스를 관리하기 위해 MySQL 을 사용하고 데이터베이스와 JSP를 연동하기 위해 JDBC 를 사용한다.
JDBC란? 자바에서 데이터베이스 작업을 처리할 수 있게 하는 자바 라이브러리

1. 데이터베이스에 상품 테이블 만들기

MySQL 설치 후 MySQL workbench 에서 데이터베이스, 상품 테이블을 생성하는 SQL문 작성
(SQL은 추후 더 자세히 배울 예정)

// webmarketdb 데이터베이스 생성
CREATE database webmarketdb default character set utf8 collate utf8_general_ci;

// 사용할 데이터베이스 지정
USE WebMarketDB;

// product 테이블 생성, 기본 키 p_id
CREATE TABLE IF NOT EXISTS product(
	p_id VARCHAR(10) NOT NULL,
	p_name VARCHAR(20),
	p_unitPrice INTEGER,
	p_description TEXT,
   	p_category VARCHAR(20),
	p_manufacturer VARCHAR(20),
	p_unitsInStock LONG,
	p_condition VARCHAR(20),
	p_fileName  VARCHAR(20),
	PRIMARY KEY (p_id)
)default CHARSET=utf8;

// 테이블에 상품 추가하기
INSERT INTO product VALUES('P1234', 'iPhone 6s', 800000, '1334X750 Renina HD display, 8-megapixel iSight Camera','Smart Phone', 'Apple', 1000, 'new', 'p1234.jpg');
INSERT INTO product VALUES('P1235', 'LG PC gram', 1500000, '3.3-inch,IPS LED display, 5rd Generation Intel Core processors', 'Notebook', 'LG', 1000, 'new', 'p1235.jpg');
INSERT INTO product VALUES('P1236', 'Galaxy Tab S', 900000, '3.3-inch, 212.8*125.6*6.6mm,  Super AMOLED display, Octa-Core processor', 'Tablet', 'Samsung', 1000, 'new', 'p1236.jpg');

2. 데이터베이스 연결 페이지 만들기

mysql-connector-java-8.0.29.jar 라이브러리를 lib 폴더에 저장하고 자바와 데이터베이스를 연결하는 페이지 작성
데이터베이스 연결이 필요한 페이지에서 해당 파일을 include

파일명 : dbconn.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%
	// DB와 jsp를 연결하는 객체
	Connection conn = null;
	
	String url = "jdbc:mysql://localhost:3306/WebMarketDB";
	String user = "root";
	String password = "1234";
	
	try {
		// 드라이버 파일 로드해오기
		Class.forName("com.mysql.jdbc.Driver");
		conn = DriverManager.getConnection(url, user, password);
	} catch(SQLException e) {
		out.println("데이터베이스 연결에 실패했습니다.<br>");
		out.println("SQLException : "+e.getMessage());
	}
%>

3. 상품 목록 페이지 수정

상품 목록을 데이터베이스에서 가져와 출력하도록 코드 수정

파일명 : products.jsp

...

<%@ page import="java.sql.*" %>
<!-- DB 연결이 필요한 페이지에 include -->
<%@ include file="dbconn.jsp" %>
  
...
  
    <div class="container">
    	<div class="row" align="center">
    		<!-- SQL 사용해 DB에서 상품 정보 가져오기 -->
    		<%
                // 데이터베이스에 SQL문을 전달하는 PreparedStatement 객체
    			PreparedStatement pstmt = null;
                // 데이터베이스로부터 결과값을 전달받는 ResultSet 객체 
    			ResultSet rs = null;
                // SQL문 작성하고 실행하기
    			String sql = "select * from product";
    			pstmt = conn.prepareStatement(sql);
    			rs = pstmt.executeQuery();
                
                // 실행한 결과값 rs(product 테이블의 모든 레코드) 하나씩 출력
    			while (rs.next()) {
    		%>
    		<div class="col-md-4 p-4">
    			<img src="./resources/images/<%= rs.getString("p_fileName") %>" style="width:100%;">
    			<h3><%= rs.getString("p_name") %></h3>
    			<p><%= rs.getString("p_description") %></p>
    			<p><%= rs.getString("p_UnitPrice") %></p>
    			<p><a href="./product.jsp?id=<%= rs.getString("p_id") %>" class="btn btn-secondary" role="button">상세 정보 &raquo;</a></p>
	    	</div>
    		<%
    			}
    		%>    		
    	</div>
        
...

4. 상품 등록 페이지 수정

새로 추가하는 상품이 데이터베이스에 등록되도록 코드 수정

파일명 : processAddProduct.jsp

<%@ page import="java.sql.*" %>
<%@ include file="dbconn.jsp" %>

...
	
	// SQL 사용해 DB에 상품 등록하기
	PreparedStatement pstmt = null;
	String sql = "insert into product values(?,?,?,?,?,?,?,?,?)";
	pstmt = conn.prepareStatement(sql);
	
	pstmt.setString(1, productId);
	pstmt.setString(2, name);
	pstmt.setInt(3, price);
	pstmt.setString(4, description);
	pstmt.setString(5, category);
	pstmt.setString(6, manufacturer);
	pstmt.setLong(7, stock);
	pstmt.setString(8, condition);
	pstmt.setString(9, productImage);
	pstmt.executeUpdate();
	
	if(pstmt != null) {
		pstmt.close();
	}
	if(conn != null) {
		conn.close();
	}
	
	// 상품 목록 페이지로 이동
	response.sendRedirect("products.jsp");
%>

5. 상품 편집/삭제 페이지 만들기


같은 페이지에서 edit 파라미터 값이 update 면 수정 버튼, delete 면 삭제 버튼이 나오도록 함
수정 버튼을 클릭하면 updateProduct.jsp 페이지로,
삭제 버튼을 클릭하면 deleteProduct.jsp 로 상품 id 가지고 이동

파일명 : editProduct.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>상품 편집</title>
<script>
	function deleteConfirm(id) {
		if (confirm("해당 상품을 삭제합니다!!") == true) {
			location.href = "./deleteProduct.jsp?id="+id;
		} else {return;}
	}
</script>
<link rel="stylesheet" href="./resources/css/bootstrap.min.css">
</head>
<%
	String edit = request.getParameter("edit");
%>
<body>
	<!-- menu -->
    <jsp:include page="menu.jsp" />
    
    <!-- jumbotron -->
    <div class="jumbotron">
        <div class="container">
            <h1 class="display-3">상품 편집</h1>
        </div>
    </div>
 
    <div class="container">
    	<div class="row" align="center">
    		<!-- DB 연결이 필요한 페이지에 include -->
    		<%@ include file="dbconn.jsp" %>
    		<!-- SQL 사용해 DB에서 상품 정보 가져오기 -->
    		<%
    			PreparedStatement pstmt = null;
    			ResultSet rs = null;
    			String sql = "select * from product";
    			pstmt = conn.prepareStatement(sql);
    			rs = pstmt.executeQuery();
    			while (rs.next()) {
    		%>
    		<div class="col-md-4 p-4">
    			<img src="./resources/images/<%= rs.getString("p_fileName") %>" style="width:100%;">
    			<h3><%= rs.getString("p_name") %></h3>
    			<p><%= rs.getString("p_description") %></p>
    			<p><%= rs.getString("p_UnitPrice") %></p>
    			<!-- 상품 아이디를 id 변수에 담아 파라미터로 전달 -->
    			<p>
    				<%
    					if(edit.equals("update")) {
    				%>
    				<a href="./updateProduct.jsp?id=<%= rs.getString("p_id") %>" class="btn btn-success" role="button">수정 &raquo;</a>
    				<%
    					} else if(edit.equals("delete")) {
    				%>
    				<a href="#" onclick="deleteConfirm('<%= rs.getString("p_id") %>')" class="btn btn-success" role="button">삭제 &raquo;</a>
    				<%
    					}
    				%>
    			</p>
	    	</div>
    		<%
    			}
    			
    			if (rs != null) { rs.close(); }
    			if (pstmt != null) { pstmt.close(); }
    			if (conn != null) { conn.close(); }
    		%>
    		
    	</div>
    	<hr>
    </div>
    
    <!-- footer -->
    <jsp:include page="footer.jsp" />
</body>
</html>

5-1. 상품 수정 내용 입력 페이지 작성

폼을 제출하면 processUpdateProduct.jsp 에서 처리

파일명 : updateProduct.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%@ include file="dbconn.jsp" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>상품 수정</title>
<link rel="stylesheet" href="./resources/css/bootstrap.min.css">
</head>
<%
	String edit = request.getParameter("edit");
%>
<body>
	<!-- menu -->
    <jsp:include page="menu.jsp" />
    
    <!-- jumbotron -->
    <div class="jumbotron">
        <div class="container">
            <h1 class="display-3">상품 수정</h1>
        </div>
    </div>

 	<%
 		String productId = request.getParameter("id");
 		
	 	PreparedStatement pstmt = null;
		ResultSet rs = null;
        
        // 데이터베이스에서 상품 id가 productId인 레코드 찾기
		String sql = "select * from product where p_id = ?";
		pstmt = conn.prepareStatement(sql);
		pstmt.setString(1, productId);
		rs = pstmt.executeQuery();
        
        // 레코드가 존재하면 다음 내용 실행
		if (rs.next()) {
 	%>
 	<div class="container">
 		<div class="row">
 			<div class="col-md-5">
 				<img src="./resources/images/<%= rs.getString("p_fileName") %>" style="width:100%;">
 			</div>
 			<div class="col-md-7">
 				<form name="newProduct" action="./processUpdateProduct.jsp" class="form-horizontal" method="post" enctype="multipart/form-data">
 					<div class="form-group row">
		    			<label class="col-sm-2">상품 코드</label>
		    			<div class="col-sm-3">
		    				<input type="text" id="productId" name="productId" class="form-control" value='<%= rs.getString("p_id") %>'>
		    			</div>
		    		</div>
		    		<div class="form-group row">
		    			<label class="col-sm-2">상품명</label>
		    			<div class="col-sm-3">
		    				<input type="text" id="name" name="name" class="form-control" value='<%= rs.getString("p_name") %>'>
		    			</div>
		    		</div>
		    		<div class="form-group row">
		    			<label class="col-sm-2">가격</label>
		    			<div class="col-sm-3">
		    				<input type="text" id="unitPrice" name="unitPrice" class="form-control" value='<%= rs.getInt("p_unitPrice") %>'>
		    			</div>
		    		</div>
		    		<div class="form-group row">
		    			<label class="col-sm-2">상세 설명</label>
		    			<div class="col-sm-5">
		    				<textarea name="description" cols="50" rows="2" class="form-control"><%= rs.getString("p_description") %></textarea>
		    			</div>
		    		</div>
		    		<div class="form-group row">
		    			<label class="col-sm-2">제조사</label>
		    			<div class="col-sm-3">
		    				<input type="text" name="manufacturer" class="form-control" value='<%= rs.getString("p_manufacturer") %>'>
		    			</div>
		    		</div>
		    		<div class="form-group row">
		    			<label class="col-sm-2">분류</label>
		    			<div class="col-sm-3">
		    				<!-- 이미 선택된 category에 checked 되게 하는 방법? -->
		    				<select name="category" class="custom-select">
		    					<option value="Smart Phone">스마트폰</option>
		    					<option value="Notebook">노트북</option>
		    					<option value="Tablet">태블릿</option>
		    					<option value="Others">기타</option>
		    				</select>
		    			</div>
		    		</div>
		    		<div class="form-group row">
		    			<label class="col-sm-2">재고 수</label>
		    			<div class="col-sm-3">
		    				<input type="text" id="unitsInStock" name="unitsInStock" class="form-control" value='<%= rs.getLong("p_unitsInStock") %>'>
		    			</div>
		    		</div>
		    		<div class="form-group row">
		    			<label class="col-sm-2">상태</label>
		    			<div class="col-sm-5">
		    				<input type="radio" name="condition" value="New">
		    				신규 제품
		    				<input type="radio" name="condition" value="Old">
		    				중고 제품
		    				<input type="radio" name="condition" value="Refurbished">
		    				재생 제품
		    			</div>
		    		</div>
		    		<div class="form-group row">
		    			<label class="col-sm-2">이미지</label>
		    			<div class="col-sm-5">
		    				<input type="file" name="productImage" class="form-control">
		    			</div>
		    		</div>
		    		<div class="form-group row">
		    			<div class="col-sm-offset-2 col-sm-10">
		    				<input type="submit" class="btn btn-primary" value="등록">
		    			</div>
		    		</div>
 				</form>
 			</div>
 		</div>
 		<hr>
 	</div>
 	<%
		}
		
		if (rs != null) { rs.close(); }
		if (pstmt != null) { pstmt.close(); }
		if (conn != null) { conn.close(); }
	%>
	
    <!-- footer -->
    <jsp:include page="footer.jsp" />
</body>
</html>

5-2. 상품 수정 처리 페이지 작성

전달받은 파라미터를 변수에 담고
상품 아이디로 수정할 상품 레코드를 데이터베이스에서 가져와
담은 변수를 set하고 해당 레코드를 update

파일명 : processUpdateProduct.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="com.oreilly.servlet.*" %>
<%@ page import="com.oreilly.servlet.multipart.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.sql.*" %>
<%@ include file="dbconn.jsp" %>

<%

	// 파일을 전달받기 위한 작업
	String path = "./resources/images";
	String savedir = request.getServletContext().getRealPath(path);
	int maxSize = 5*1024*1024;
	String encType = "utf-8";
	
	// 전달값 접근을 위한 MultipartRequest 객체 생성
	MultipartRequest multi = new MultipartRequest(request, savedir, maxSize, encType);

	// 전달받은 파라미터 담기
	String productId = multi.getParameter("productId");
	String name = multi.getParameter("name");
	String unitPrice = multi.getParameter("unitPrice");
	String description = multi.getParameter("description");
	String manufacturer = multi.getParameter("manufacturer");
	String category = multi.getParameter("category");
	String unitsInStock = multi.getParameter("unitsInStock");
	String condition = multi.getParameter("condition");
	
	// Product 객체에 set하기 위해 일부 값은 형변환 필요
	Integer price;
	
	if(unitPrice.isEmpty()) {
		price = 0;
	} else {
		price = Integer.valueOf(unitPrice);
	}
	
	long stock;
	if(unitsInStock.isEmpty()) {
		stock = 0;
	} else {
		stock = Long.valueOf(unitsInStock);
	}
	
	// 이미지 파일 이름 가져오기
	String productImage = multi.getFilesystemName("productImage");

	PreparedStatement pstmt = null;
	ResultSet rs = null;
	
    // DB에서 수정할 상품 찾아 가져오기
	String sql = "select * from product where p_id = ?";
	pstmt = conn.prepareStatement(sql);
	pstmt.setString(1, productId);
	rs = pstmt.executeQuery();
	
	if(rs.next()) {
		// 업로드한 파일이 있으면
		if (productImage != null) {
        	// p_id가 ~인 레코드의 내용 수정
			sql = "UPDATE product SET p_name=?, p_unitPrice=?, p_description=?, p_manufacturer=?, p_category=?, p_unitsInStock=?, p_condition=?, p_fileName=? WHERE p_id=?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, name);
			pstmt.setInt(2, price);
			pstmt.setString(3, description);
			pstmt.setString(4, manufacturer);
			pstmt.setString(5, category);
			pstmt.setLong(6, stock);
			pstmt.setString(7, condition);
			pstmt.setString(8, productImage);
			pstmt.setString(9, productId);
			pstmt.executeUpdate();
		}
		// 업로드한 파일이 없으면
		else {
			sql = "UPDATE product SET p_name=?, p_unitPrice=?, p_description=?, p_manufacturer=?, p_category=?, p_unitsInStock=?, p_condition=? WHERE p_id=?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, name);
			pstmt.setInt(2, price);
			pstmt.setString(3, description);
			pstmt.setString(4, manufacturer);
			pstmt.setString(5, category);
			pstmt.setLong(6, stock);
			pstmt.setString(7, condition);
			pstmt.setString(8, productId);
			pstmt.executeUpdate();
		}
	}
	
	if (rs != null) { rs.close(); }
	if (pstmt != null) { pstmt.close(); }
	if (conn != null) { conn.close(); }
	
	// 상품 수정 페이지로 이동
	response.sendRedirect("editProduct.jsp?edit=update");
%>

5-3. 상품 삭제 처리 페이지 작성

파일명 : deleteProduct.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%@ include file="dbconn.jsp" %>

<%
	String productId = request.getParameter("id");

	PreparedStatement pstmt = null;
	ResultSet rs = null;
	
	String sql = "select * from product";
	pstmt = conn.prepareStatement(sql);
	rs = pstmt.executeQuery();
	
	if (rs.next()) {
 	    // p_id가 ~인 레코드 삭제
		sql = "delete from product where p_id = ?";
		pstmt = conn.prepareStatement(sql);
		pstmt.setString(1, productId);
		pstmt.executeUpdate();
	} else {
		out.println("일치하는 상품이 없습니다.");
	}
	
	if (rs != null) { rs.close(); }
	if (pstmt != null) { pstmt.close(); }
	if (conn != null) { conn.close(); }
	
	// 상품 삭제 페이지로 이동
	response.sendRedirect("editProduct.jsp?edit=delete");
%>

5-4. 메뉴 수정

상품 목록, 등록, 수정, 삭제 메뉴 추가

파일명 : menu.jsp

<%@ page contentType="text/html; charset=UTF-8"%>
<nav class="navbar navbar-expand navbar-dark bg-dark">
    <div class="container">
        <div class="navbar-header">
            <a href="./welcome.jsp" class="navbar-brand">
                Home
            </a>
        </div>
        <div>
        	<ul class="navbar-nav mr-auto">
        		<li class="nav-item">
        			<a href="./products.jsp" class="nav-link">상품 목록</a>
        		</li>
        		<li class="nav-item">
        			<a href="./addProduct.jsp" class="nav-link">상품 등록</a>
        		</li>
        		<li class="nav-item">
        			<a href="./editProduct.jsp?edit=update" class="nav-link">상품 수정</a>
        		</li>
        		<li class="nav-item">
        			<a href="./editProduct.jsp?edit=delete" class="nav-link">상품 삭제</a>
        		</li>
        	</ul>
        </div>
    </div>
</nav>
profile
🌱

0개의 댓글