selectTest.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.Date" %>
<%@ page import="java.sql.SQLException" %>
<%@ include file="dbinfo.jspf" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판 목록</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="page-main">
<h2>게시판 목록</h2>
<div class="align-right">
<input type="button" value="글쓰기" onclick="location.href='insertTestForm.jsp'">
</div>
<%
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = null;
try {
// JDBC 수행 1단계 : 드라이버 로드
Class.forName(driverName);
// JDBC 수행 2단계 : Connection 객체 생성
conn = DriverManager.getConnection(jdbcUrl, dbId, dbPass);
// SQL문 작성
sql = "SELECT * FROM tboard ORDER BY num DESC";
// JDBC 수행 3단계 : PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// JDBC 수행 4단계 : SQL문을 실행하고 결과 행을 ResultSet에 담아 반환
rs = pstmt.executeQuery();
%>
<table>
<tr>
<th>글 번호</th>
<th>제목</th>
<th>작성자</th>
<th>작성일</th>
</tr>
<%
while(rs.next()) {
int num = rs.getInt("num");
String name = rs.getString("name");
String title = rs.getString("title");
Date reg_date = rs.getDate("reg_date");
%>
<tr>
<td><%= num %></td>
<td><a href="detailTest.jsp?num=<%= num %>"><%= title %></a></td> <%-- 제목에 상세 페이지 링크를 걸고 GET 방식으로 글 번호를 전달 --%>
<td><%= name %></td>
<td><span title="<%= rs.getString("reg_date") %>"><%= reg_date %></span></td>
</tr>
<%
}
%>
</table>
<%
}
catch(Exception e) {
e.printStackTrace();
%>
<div class="result-display">
<span>오류 발생!</span>
</div>
<%
}
finally {
// 자원 정리
if(rs!=null) try {rs.close();} catch(SQLException e) {}
if(pstmt!=null) try {pstmt.close();} catch(SQLException e) {}
if(conn!=null) try {conn.close();} catch(SQLException e) {}
}
%>
</div>
</body>
</html>
style.css
하단에 다음의 내용을 추가/* 목록 */
table {
width: 100%;
border: 1px solid #000;
border-collapse: collapse;
margin-top: 5px;
}
table td, table th {
border: 1px solid #000;
padding: 5px;
}
detailTest.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.Date" %>
<%@ page import="java.sql.SQLException" %>
<%@ include file="dbinfo.jspf" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글 상세 정보 보기</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<%
int num = Integer.parseInt(request.getParameter("num"));
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = null;
try {
// JDBC 수행 1단계 : 드라이버 로드
Class.forName(driverName);
// JDBC 수행 2단계 : Connection 객체 생성
conn = DriverManager.getConnection(jdbcUrl, dbId, dbPass);
// SQL문 작성
sql = "SELECT * FROM tboard WHERE num=?";
// JDBC 수행 3단계 : PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// ?에 데이터를 바인딩
pstmt.setInt(1, num);
// JDBC 수행 4단계 : SQL문을 실행해서 결과 행을 ResultSet에 담아 반환
rs = pstmt.executeQuery();
if(rs.next()) { // 행이 존재하는 경우
String name = rs.getString("name");
String title = rs.getString("title");
String content = rs.getString("content");
Date reg_date = rs.getDate("reg_date");
%>
<div class="page-main">
<h2>글 상세 정보</h2>
<ul>
<li>글 번호 : <%= num %></li>
<li>제목 : <%= title %></li>
<li>작성자 : <%= name %></li>
<li title="<%= rs.getString("reg_date") %>">작성일 : <%= reg_date %></li>
</ul>
<hr width="100%" size="1" noshade="noshade">
<p>
<%= content %>
</p>
<hr width="100%" size="1" noshade="noshade">
<div class="align-right">
<input type="button" value="수정" onclick="location.href='updateTestForm.jsp?num=<%= num %>'">
<input type="button" value="삭제" onclick="location.href='deleteTestForm.jsp?num=<%= num %>'">
<input type="button" value="목록" onclick="location.href='selectTest.jsp'">
</div>
</div>
<%
}
else { // 행이 존재하지 않는 경우
%>
<div class="result-display">
<div class="align-center">
글 상세 정보가 없습니다!<br>
<input type="button" value="목록" onclick="location.href='selectTest.jsp'">
</div>
</div>
<%
}
}
catch(Exception e) {
e.printStackTrace();
%>
<div class="result-display">
<div class="align-center">
오류 발생! 글 상세 정보 호출 실패<br>
<input type="button" value="목록" onclick="location.href='selectTest.jsp'">
</div>
</div>
<%
}
finally {
// 자원 정리
if(rs!=null) try {rs.close();} catch(SQLException e) {}
if(pstmt!=null) try {pstmt.close();} catch(SQLException e) {}
if(conn!=null) try {conn.close();} catch(SQLException e) {}
}
%>
</body>
</html>
updateTestForm.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.Date" %>
<%@ page import="java.sql.SQLException" %>
<%@ include file="dbinfo.jspf" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글 수정</title>
<link rel="stylesheet" href="style.css">
<script type="text/javascript">
window.onload = function() {
var myForm = document.getElementById('myForm');
// 이벤트 연결
myForm.onsubmit = function() {
list = document.getElementsByTagName('li');
for(let i=0;i<list.length;i++) {
let input = list[i].querySelector('input,textarea');
if(input.value.trim()=='') {
let label = list[i].querySelector('label').innerHTML;
let post = ((label.charCodeAt(label.length-1) - 44032) % 28) > 0 ? '을' : '를'; // 주어진 단어의 마지막 글자에 받침(=종성)이 있으면 을, 없으면 를; 44032는 유니코드에서 첫 번째 한글인 '가'의 10진수 값
alert(label + post + ' 입력하세요!');
input.focus();
input.value = '';
return false;
}
}
};
};
</script>
</head>
<body>
<%
int num = Integer.parseInt(request.getParameter("num"));
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = null;
try {
// JDBC 수행 1단계 : 드라이버 로드
Class.forName(driverName);
// JDBC 수행 2단계 : Connection 객체 생성
conn = DriverManager.getConnection(jdbcUrl, dbId, dbPass);
// SQL문 작성
sql = "SELECT * FROM tboard WHERE num=?";
// JDBC 수행 3단계 : PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// ?에 데이터를 바인딩
pstmt.setInt(1, num);
// JDBC 수행 4단계 : SQL문을 실행하고 결과 행을 ResultSet에 담아 반환
rs = pstmt.executeQuery();
if(rs.next()) { // 행이 있는 경우
String name = rs.getString("name");
String title = rs.getString("title");
String content = rs.getString("content");
%>
<div class="page-main">
<h2>글 수정</h2>
<form id="myForm" action="updateTest.jsp" method="post">
<input type="hidden" name="num" value="<%= num %>"> <!-- type을 hidden으로 지정하면 해당 태그가 화면에 보이지 않아 사용자는 수정할 수 없지만 서버에는 값이 전송됨 -->
<ul>
<li>
<label for="name">이름</label>
<input type="text" name="name" id="name" value="<%= name %>" size="10" maxlength="10">
</li>
<li>
<label for="title">제목</label>
<input type="text" name="title" id="title" value="<%= title %>">
</li>
<li>
<label for="content">내용</label>
<textarea rows="5" cols="40" name="content" id="content"><%= content %></textarea> <!-- <textarea> 태그는 시작 태그와 끝 태그 사이에 미리보기 내용을 넣어야 하며, 개행문자나 \t등도 모두 태그의 내용으로 인식되기 때문에 불필요한 공백을 넣지 말아야 함 -->
</li>
</ul>
<div class="align-center">
<input type="submit" value="수정">
<input type="button" value="목록" onclick="location.href='selectTest.jsp'">
</div>
</form>
</div>
<%
}
else { // 행이 없는 경우
%>
<div class="result-display">
<div class="align-center">
수정할 글 정보 호출 실패!<br>
<input type="button" value="목록" onclick="location.href='selectTest.jsp'">
</div>
</div>
<%
}
}
catch(Exception e) {
e.printStackTrace();
%>
<div class="result-display">
<div class="align-center">
오류 발생! 수정할 글 정보 호출 실패!<br>
<input type="button" value="목록" onclick="location.href='selectTest.jsp'">
</div>
</div>
<%
}
finally {
// 자원 정리
if(rs!=null) try {rs.close();} catch(SQLException e) {}
if(pstmt!=null) try {pstmt.close();} catch(SQLException e) {}
if(conn!=null) try {conn.close();} catch(SQLException e) {}
}
%>
</body>
</html>
updateTest.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.SQLException" %>
<%@ include file="dbinfo.jspf" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글 수정</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<%
// 전송된 데이터 인코딩 처리
request.setCharacterEncoding("UTF-8");
// 전송된 데이터 반환
int num = Integer.parseInt(request.getParameter("num"));
String name = request.getParameter("name");
String title = request.getParameter("title");
String content = request.getParameter("content");
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
try {
// JDBC 수행 1단계 : 드라이버 로드
Class.forName(driverName);
// JDBC 수행 2단계 : Connection 객체 생성
conn = DriverManager.getConnection(jdbcUrl, dbId, dbPass);
// SQL문 작성
sql = "UPDATE tboard SET name=?, title=?, content=?, reg_date=SYSDATE WHERE num=?";
// JDBC 수행 3단계 : PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// ?에 데이터를 바인딩
pstmt.setString(1, name);
pstmt.setString(2, title);
pstmt.setString(3, content);
pstmt.setInt(4, num);
// JDBC 수행 4단계 : SQL문 실행
pstmt.executeUpdate();
%>
<div class="result-display">
<div class="align-center">
글 수정 완료!<br>
<input type="button" value="상세 페이지" onclick="location.href='detailTest.jsp?num=<%= num %>'">
<input type="button" value="목록" onclick="location.href='selectTest.jsp'">
</div>
</div>
<%
}
catch(Exception e) {
e.printStackTrace();
%>
<div class="result-display">
<div class="align-center">
오류 발생! 글 수정 실패<br>
<input type="button" value="글 수정하기" onclick="location.href='updateTestForm.jsp?num=<%= num %>'">
</div>
</div>
<%
}
finally {
// 자원 정리
if(pstmt!=null) try {pstmt.close();} catch(SQLException e) {}
if(conn!=null) try {conn.close();} catch(SQLException e) {}
}
%>
</body>
</html>
deleteTestForm.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글 삭제</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<%
int num = Integer.parseInt(request.getParameter("num"));
%>
<div class="page-main">
<h2>글 삭제</h2>
<p class="align-center">
<span>정말 삭제하시겠습니까?</span>
</p>
<form action="deleteTest.jsp" method="post">
<input type="hidden" name="num" value="<%= num %>">
<div class="align-center">
<input type="submit" value="삭제">
<input type="button" value="목록" onclick="location.href='selectTest.jsp'">
</div>
</form>
</div>
</body>
</html>
deleteTest.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.SQLException" %>
<%@ include file="dbinfo.jspf" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글 삭제</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<%
// 전송된 데이터 인코딩 처리
request.setCharacterEncoding("UTF-8");
// 전송된 데이터 반환
int num = Integer.parseInt(request.getParameter("num"));
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
try {
// JDBC 수행 1단계 : 드라이버 로드
Class.forName(driverName);
// JDBC 수행 2단계 : Connection 객체 생성
conn = DriverManager.getConnection(jdbcUrl, dbId, dbPass);
// SQL문 작성
sql = "DELETE FROM tboard WHERE num=?";
// JDBC 수행 3단계 : PreparedStatement 객체 생성
pstmt = conn.prepareStatement(sql);
// ?에 데이터를 바인딩
pstmt.setInt(1, num);
// JDBC 수행 4단계 : SQL문 실행
pstmt.executeUpdate();
%>
<div class="result-display">
<div class="align-center">
글 삭제 완료!<br>
<input type="button" value="목록" onclick="location.href='selectTest.jsp'">
</div>
</div>
<%
}
catch(Exception e) {
e.printStackTrace();
%>
<div class="result-display">
<div class="align-center">
오류 발생! 글 삭제 실패!<br>
<input type="button" value="목록" onclick="location.href='selectTest.jsp'">
</div>
</div>
<%
}
finally {
// 자원 정리
if(pstmt!=null) try {pstmt.close();} catch(SQLException e) {}
if(conn!=null) try {conn.close();} catch(SQLException e) {}
}
%>
</body>
</html>
ch11-jdbc
생성하고 table.sql
생성CREATE TABLE product (
num NUMBER PRIMARY KEY,
name VARCHAR2(30) NOT NULL,
price NUMBER(9) NOT NULL,
stock NUMBER(9) NOT NULL,
origin VARCHAR2(30) NOT NULL,
reg_date DATE NOT NULL
);
CREATE SEQUENCE product_seq;
ch10-jdbc
폴더의 style.css
와 dbinfo.jspf
를 복사하여 ch11-jdbc
폴더에 붙여넣기insertTestForm.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>상품 등록</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="page-main">
<h2 class="align-center">상품 등록</h2>
<form id="myForm" action="insertTest.jsp" method="post">
<ul>
<li>
<label for="name">상품명</label>
<input type="text" name="name" id="name">
</li>
<li>
<label for="price">가격</label>
<input type="number" name="price" id="price" min="1" placeholder="1 ~ 999,999,999"> <!-- 가격이 0이면 무의미하기 때문에 최솟값은 1로 설정 -->
</li>
<li>
<label for="stock">재고</label>
<input type="number" name="stock" id="stock" min="0" placeholder="0 ~ 999,999,999"> <!-- max값에 연산 식을 넣을 수 없으며, max값을 직접 999999999로 지정시 JavaScript를 통한 입력 값 길이 제어가 제대로 동작하지 않음 -->
</li>
<li>
<label for="origin">원산지</label>
<input type="text" name="origin" id="origin">
</li>
</ul>
<div class="align-center">
<input type="submit" value="상품 등록">
<input type="button" value="상품 목록" onclick="location.href='selectTest.jsp'">
</div>
</form>
</div>
<script type="text/javascript">
document.querySelector('form').onsubmit = function() {
let list = document.getElementsByTagName('li');
for(let i=0;i<list.length;i++) {
let input = list[i].querySelector('input');
input.value = input.value.trim(); // 입력된 값 양 끝의 공백 제거
if(!input.value) { // 아무것도 입력하지 않은 경우
let label = list[i].querySelector('label').textContent; // 현재 입력 필드에 대응하는 <label> 태그 선택
let post = ((label.charCodeAt(label.length-1) - 44032) % 28) > 0 ? '을' : '를'; // 항목명의 받침 유무에 따라 적절한 조사 선택
alert(label + post + ' 입력하세요!');
input.focus();
return false;
}
}
};
let nums = document.querySelectorAll('input[type="number"]');
for(let i=0;i<nums.length;i++) {
nums[i].onkeyup = function() {
if(this.value.length>9) { // 입력된 숫자가 9자리를 초과하면
this.value = this.value.slice(0, 9); // 10번째 이후 숫자를 제거
}
};
}
let texts = document.querySelectorAll('input[type="text"]');
for(let i=0;i<texts.length;i++) {
texts[i].onkeyup = function() {
while(getBytesLength(this.value)>30) { // 입력된 값이 30bytes를 초과하는 동안
this.value = this.value.slice(0, -1); // 마지막 글자를 제거
}
};
}
function getBytesLength(str) {
let bytes = 0;
for(let i=0;i<str.length;i++) {
let unicode = str.charCodeAt(i);
bytes += unicode >> 11 ? 3 : (unicode >> 7 ? 2 : 1); // 2^11=2048로 나누었을 때 몫이 있으면 3bytes, 그보다 작은 수이면서 2^7=128로 나누었을 때 몫이 있으면 2bytes, 그 외에는 1byte
}
return bytes;
}
</script>
</body>
</html>
insertTest.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.SQLException" %>
<%@ include file="dbinfo.jspf" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>상품 등록 처리</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
int price = Integer.parseInt(request.getParameter("price"));
int stock = Integer.parseInt(request.getParameter("stock"));
String origin = request.getParameter("origin");
Connection conn = null;
PreparedStatement pstmt = null;
String sql = null;
try {
Class.forName(driverName);
conn = DriverManager.getConnection(jdbcUrl, dbId, dbPass);
sql = "INSERT INTO product (num, name, price, stock, origin, reg_date) "
+ "VALUES (product_seq.NEXTVAL, ?, ?, ?, ?, SYSDATE)";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, name);
pstmt.setInt(2, price);
pstmt.setInt(3, stock);
pstmt.setString(4, origin);
pstmt.executeUpdate();
%>
<div class="result-display">
<div class="align-center">
상품 등록에 성공하였습니다!<br>
<input type="button" value="추가 등록" onclick="location.href = 'insertTestForm.jsp';">
<input type="button" value="상품 목록" onclick="location.href = 'selectTest.jsp';">
</div>
</div>
<%
}
catch(Exception e) {
e.printStackTrace();
%>
<div class="result-display">
<div class="align-center">
상품 등록에 실패하였습니다!<br>
3초 후 이전 페이지로 이동합니다.
</div>
</div>
<script type="text/javascript"> /* <div> 태그는 onload 이벤트를 지원하지 않음 */
setTimeout(function() {history.back();}, 3000);
</script>
<%
}
finally {
if(pstmt!=null) try {pstmt.close();} catch(SQLException e) {}
if(conn!=null) try {conn.close();} catch(SQLException e) {}
}
%>
</body>
</html>
selectTest.jsp
생성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.Date" %>
<%@ page import="java.sql.SQLException" %>
<%@ include file="dbinfo.jspf" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>상품 목록</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="page-main">
<h2 class="align-center">상품 목록</h2>
<div class="align-right">
<input type="button" value="상품 등록" onclick="location.href = 'insertTestForm.jsp';">
</div>
<%
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = null;
try {
Class.forName(driverName);
conn = DriverManager.getConnection(jdbcUrl, dbId, dbPass);
sql = "SELECT * FROM product ORDER BY num DESC";
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
%>
<table>
<tr>
<th>상품 번호</th>
<th>상품명</th>
<th>가격 <small>(원)</small></th>
<th>재고 <small>(개)</small></th>
</tr>
<%
while(rs.next()) {
int num = rs.getInt("num");
%>
<tr>
<td><%= num %></td>
<td><a href="detailTest.jsp?num=<%= num %>"><%= rs.getString("name") %></a></td>
<td><%= String.format("%,d", rs.getInt("price")) %></td>
<td><%= String.format("%,d", rs.getInt("stock")) %></td>
</tr>
<%
}
%>
</table>
<%
}
catch(Exception e) {
e.printStackTrace();
%>
<div class="result-display">
<span>오류 발생!</span>>
</div>
<%
}
finally {
if(rs!=null) try {rs.close();} catch(SQLException e) {}
if(pstmt!=null) try {pstmt.close();} catch(SQLException e) {}
if(conn!=null) try {conn.close();} catch(SQLException e) {}
}
%>
</div>
</body>
</html>