글 수정 구현
하나둘씩 기능을 만들어갈수록 새로 구현하는 기능들이 처음부터 끝까지 다 다른 내용이 아니라, 기존에 구현한 내용들과 어느 정도 유사성을 가진다는 것을 알 수 있습니다.
어떻게 보면 수정 시 필요한 jsp 파일들은 view.jsp와 write.jsp, writeOk.jsp를 섞어놓은 것이라고 볼 수 있습니다.
BookController
case "/update.do":
command = new SelectCommand();
command.execute(request, response);
viewPage = "update.jsp";
break;
case "/updateOk.do":
command = new UpdateCommand();
command.execute(request, response);
viewPage = "updateOk.jsp";
break;
update.do에서는 기존 글 내용을 불러와야 하므로 SELECT 기능을 수행하는 command가 필요합니다.
updateOk.do에서는 update.do에서 수정된 내용을 받아와 데이터베이스에 UPDATE 합니다.
SelectCommand
package com.command;
import java.sql.SQLException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.beans.BookDAO;
import com.beans.BookDTO;
public class SelectCommand implements Command {
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) {
int uid = Integer.parseInt(request.getParameter("uid"));
List<BookDTO> list = null;
try {
list = new BookDAO().selectByUid(uid);
} catch (SQLException e) {
e.printStackTrace();
}
request.setAttribute("list", list);
}
}
parameter 값으로 가져온 uid와 데이터베이스의 bk_uid가 일치하는 글 정보를 가지고 옵니다.
view에서 사용했던 readByUid() 메서드와는 다른 selectByUid() 메서드입니다.
BookDAO().selectByUid()
public List<BookDTO> selectByUid(int uid) throws SQLException {
List<BookDTO> list = null;
try {
pstmt = conn.prepareStatement(D.SQL_BOOK_SELECT_BY_UID);
pstmt.setInt(1, uid);
rs = pstmt.executeQuery();
list = buildList(rs);
} finally {
close();
}
return list;
}
readByUid() 메서드에서는 조회수 증가를 위해 쿼리문 한 개를 더 사용했습니다.
selectByUid()는 단순히 글 정보만 불러올 뿐 조회수 증가는 하지 않아도 되므로 SQL_BOOK_SELECT_BY_UID 쿼리문만 사용합니다.
update.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.beans.*"%>
<%@ page import="java.util.*"%>
<%
List<BookDTO> list = (List<BookDTO>) request.getAttribute("list");
if (list == null || list.size() == 0) {
%>
<script>
alert("해당 정보가 삭제되었거나 존재하지 않습니다.");
history.back();
</script>
<%
return;
}
%>
<%
BookDTO dto = list.get(0);
int uid = dto.getUid();
String title = dto.getTitle();
String summary = dto.getSummary();
int price = dto.getPrice();
String regDate = dto.getRegDateTime();
%>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title><%=title %> 수정</title>
</head>
<body>
<h1><%=title %> 수정</h1>
<hr>
<form name="frm" action="updateOk.do" method="post" onsubmit="return chkSubmit()">
<input type="hidden" name="uid" value="<%=uid %>"/>
<strong>도서 제목</strong>
<input type="text" name="title" value="<%=title %>"/><br>
<strong>도서 가격</strong>
<input type="number" name="price" value="<%=price %>"/><br>
<strong>등록일</strong> <%=regDate %><br><br>
<strong>요약</strong><br>
<textarea name="summary"><%=summary %></textarea>
<br><br>
<input type="submit" value="수정하기"/>
</form>
<br><hr><br>
<button onclick="histroy.back()">뒤로가기</button>
<button onclick="location.href='list.do'">목록으로</button>
<script>
function chkSubmit() {
frm = document.forms['frm'];
let title = frm['title'].value.trim();
let price = frm['price'].value.trim();
if (title == '') {
alert("도서 제목은 반드시 입력해야 합니다");
frm['title'].focus();
return false;
}
if (price < 0 || price == '' || isNaN(price)) {
alert("도서 가격은 0원 이상이어야 합니다");
frm['price'].focus();
return false;
}
return true;
}
</script>
</body>
</html>
SelectCommand에서 받아온 list 정보를 불러온 뒤, 각각의 정보를 변수에 저장합니다.
view.jsp와 다른 점은, view.jsp에서는 가져온 값들을 단순한 텍스트로 출력했지만 update.jsp에서는 input 태그의 value 값으로 넣어줘야 한다는 것입니다.
uid 값은 어떤 글을 수정하냐를 알려주기 위해 필요하나 굳이 사용자에게는 노출되지 않아도 되는 정보이므로 hidden으로 처리했습니다.
등록일과 조회수 정보는 수정하지 않아도 되는 정보이니 등록일은 단순 출력만 하고, 조회수는 가져오지 않았습니다.
수정 시 title 값과 price 값 검증을 해야 하므로 두 값이 빈 값이 아닌 걸 검사하고 price 값은 0 이상의 값인지를 검사합니다.
UpdateCommand
package com.command;
import java.sql.SQLException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.beans.BookDAO;
import com.beans.BookDTO;
public class UpdateCommand implements Command {
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) {
int cnt = 0;
int uid = Integer.parseInt(request.getParameter("uid"));
String title = request.getParameter("title");
String summary = request.getParameter("summary");
int price = Integer.parseInt(request.getParameter("price"));
if ((title != null && title.trim().length() > 0) || (price > 0)) {
try {
cnt = new BookDAO().update(uid, title, summary, price);
} catch (SQLException e) {
e.printStackTrace();
}
}
request.setAttribute("result", cnt);
}
}
form에서 입력받은 값을 가져옵니다.
title 값과 price 값을 한 번 더 검증한 뒤 올바른 값이 입력되었다면 uid, title, summary, price 값을 인자 값으로 넣어 update() 메서드를 실행합니다.
BookDAO().update()
public int update(int uid, String title, String summary, int price) throws SQLException {
int cnt = 0;
try {
pstmt = conn.prepareStatement(D.SQL_BOOK_UPDATE);
pstmt.setString(1, title);
pstmt.setString(2, summary);
pstmt.setInt(3, price);
pstmt.setInt(4, uid);
cnt = pstmt.executeUpdate();
} finally {
close();
}
return cnt;
}
Query문
public static final String SQL_BOOK_UPDATE =
"UPDATE book SET bk_title = ?, bk_summary = ?, bk_price = ? WHERE bk_uid = ?";
입력받은 title, summary, price 값을 SET 절에 넣고, uid 값은 WHERE 절에 들어갑니다.
updateOk.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.beans.*" %>
<%
int cnt = (Integer)request.getAttribute("result");
int uid = Integer.parseInt(request.getParameter("uid"));
%>
<% if (cnt == 0) { %>
<script>
alert("수정 실패");
history.back();
</script>
<% } else { %>
<script>
alert("수정 성공");
location.href = "view.do?uid=<%=uid %>";
</script>
<% } %>
UPDATE 쿼리가 올바르게 실행되면 반환받은 cnt 값이 1일 것입니다. 따라서 1이 아닌 경우(여기서는 0으로 초기화를 했었으니 cnt가 0인 경우), 수정 실패 알림 창을 띄웁니다.
cnt가 1이라면 수정 성공 알림창을 띄우고 수정한 글의 view 페이지로 이동합니다.
Github
https://github.com/MJKim99/JSP_Board_Book.git