반응형
List > Create > Read > Update > Delete
1. Mapper 작성
// 이전 코드
<update id="updateBoard">
update board
set
title = #{title},
content = #{content},
upt_date = sysdate
where board_seq = #{seq}
</update>
수정할 내용은 제목과 글내용으로 설정하고, 수정된 날짜는 시스템상 현재 시간으로 설정합니다.
2. Dao, DaoImpl 작성
// Dao
// 이전 코드
void updateBoard(Map<String, Object> param);
// DaoImpl
// 이전 코드
@Override
public void updateBoard(Map<String, Object> param) {
sqlsession.update("BoardMapper.updateBoard", param);
}
수정만 할 것이니 반환은 하지 않습니다.
3. Service, ServiceImpl 작성
// Service
// 이전 코드
void updateBoard(Map<String, Object> param);
// ServiceImpl
// 이전 코드
@Override
public void updateBoard(Map<String, Object> param) {
boardDao.updateBoard(param);
}
4. Controller 작성
// 이전 코드
@RequestMapping(value="/update", method = RequestMethod.POST)
public String updateBoard(@RequestParam Map<String, Object> param) {
boardSer.updateBoard(param);
int seq = Integer.parseInt(param.get("seq").toString());
return "redirect:/read/"+seq;
}
수정 후에 원래의 상세조회 페이지로 돌아가기 위해 게시글 번호를 가져와서 return 해줍니다.
5. read.jsp 수
<!-- 바뀐 read.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<c:set var="path" value="${ pageContext.request.contextPath }" />
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/resources/assets/css/style.css">
<title>Read Page</title>
</head>
<body>
<form id='updateForm'>
<header>
<div class="container">
<h1 id='title1'>Read Page : ${board.title}</h1> <!-- 숨겨주기 위해 id를 부여 -->
<input type='hidden' id='title2' name='title' value='${board.title}'> <!-- 수정 목록 1 -->
</div>
</header>
<nav>
<div class='container'>
<ul>
<li><a href='#'>Home</a></li>
<li><a href='#'>About</a></li>
<li><a href='#'>Contact</a></li>
</ul>
</div>
</nav>
<main>
<div class='container'>
<input type='hidden' name='seq' value='${board.boardSeq }'>
<table>
<thead>
<tr>
<th rowspan="2">작성자</th>
<td rowspan="2">${board.writer }</td>
<th>업로드 날짜</th>
<td><fmt:formatDate value="${board.regDate }" pattern="yyyy-MM-dd"/></td>
</tr>
<tr>
<th>업데이트 날짜</th>
<td><fmt:formatDate value="${board.uptDate }" pattern="yyyy-MM-dd"/></td>
</tr>
</thead>
<tbody>
<tr>
<td id="readTd" colspan="4">${board.content }</td> <!-- 수정 시 숨겨주기 위해 id 부여 -->
<td id="updateTd" style="display:none;" colspan="4">
<textarea name='content'>${board.content }</textarea></td> <!-- 수정 목록 2 -->
</tr>
</tbody>
</table>
<!-- 숨기고 나타나게 해주기 위한 id를 부여, 각각의 역할 부여(onclick) -->
<button onclick='letsUpdateTime(event)' id='updateBtn'>수정</button>
<button onclick='goToPrevPage(event)' id='prevBtn'>이전</button>
<button onclick='doneUpdate(event)' id='doneUBtn' style="display:none;" >수정</button>
<button onclick='cancelUpdate(event)' id='cancelBtn' style="display:none;" >취소</button>
</div>
</main>
</form>
<aside>
<div class='container'>
<h2>Sidebar</h2>
<p>This is the sidebar</p>
</div>
</aside>
</body>
</html>
수정 목록인 title과 content는 name을 부여해줬습니다.
update 페이지로 이동하는 것보다는 수정할 부분만 바뀌는 것이 사용자 편의성에 좋을 것 같아서 위와 같이 구현해 봤습니다. 물론 새로운 페이지로 넘어가면 새로운 JSP도 만들어야 할 것이고, Controller에 method가 GET인 메소드도 만들어야 겠지요. 바꿔야 하는 것이 많다면 새로운 JSP를 만드는 것이 좋지 않을까 싶습니다
6. JQeury 작성
<script src="https://code.jquery.com/jquery-3.7.1.js" integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4=" crossorigin="anonymous"></script>
<script>
function goToPrevPage(event){
event.preventDefault();
window.history.back();
}
function letsUpdateTime(event){
event.preventDefault();
$('#updateBtn').hide();
$('#prevBtn').hide();
$('#doneUBtn').show();
$('#cancelBtn').show();
$('#readTd').hide();
$('#updateTd').show();
$('#title1').hide();
$('#title2').attr('type', 'text');
}
function doneUpdate(event){
event.preventDefault();
$('#updateForm').attr({
'action' : '/update',
'method' : 'post'
}).submit();
}
function cancelUpdate(event){
event.preventDefault();
$('#doneUBtn').hide();
$('#cancelBtn').hide();
$('#updateBtn').show();
$('#prevBtn').show();
$('#updateTd').hide();
$('#readTd').show();
$('#title1').show();
$('#title2').attr('type', 'hidden');
}
</script>
이전 버튼이 <form> 태그 안에 들어왔으니 submit을 못하게 event.preventDefault();을 추가로 넣어줬습니다.
7. 결과
후기
1. 이번에는 그 동안 해왔던 방식과 살짝 다르게 하기 위해 고민을 했었습니다. 여러 방식을 사용&경험 해보는 것이 주니어 개발자인 저에게 중요하다고 생각했기 때문입니다.
2. Title을 다른 게시물 정보들과는 다르게 <head> 태그에 따로 넣어놔서 고민을 잠깐 했지만 어차피 <form> 태그로 넘길 것들은 제가 정할 수 있으니 전부 <form> 태그로 감싸줬습니다.
3. 기능 구현에만 집중을 해서 Read Page : Title 의 이쁜 모양이 망가지는 것에 신경쓰지 못했네요!
이번엔 특별히 에러를 만나지 않고 실수한 것들만 고치면 됐었습니다.
실수1. 수정 목록들을 Mapper 에서 미리 지정해줬음 에도 불구하고 title을 빼먹었고, 수정에 필요한 board_seq도 빼먹었습니다. 금방 깨닫고 고칠 수 있었습니다.
실수2. Mapper 에서 수정 조건으로 where board_seq = #{seq} 로 변수이름으로는 seq로 정했으면서 Contoller와 JSP에서 boardSeq로 지정하는 실수를 했습니다. 다행히 에러 메세지 nullpointerexception을 보고 금방 boardSeq에서 seq로 고쳐서 해결할 수 있었습니다.
기존에는 boardSeq면 boardSeq, writer면 writer 이런 식으로 같은 이름만 써줬기 때문에 정확히 class, 메소드 등등 서로 매칭되는 것이 무엇인지 파악하지 못했지만 이런 경험으로 파악해 나갈 수 있어서 좋은 경험이라고 생각했습니다. 하지만 가독성 면에서는 seq로 사용하기 보다는 모두 boardSeq로 지정하는 것이 나을 것 같았습니다.
이번에는 Read 페이지에서 URL 이동 없이 Update 하는 것을 구현해봤습니다.
다음엔 Delete로 돌아오겠습니다! 빠잇!
반응형
'Spring > CRUD Project' 카테고리의 다른 글
[CRUD] 검색 (1) | 2023.11.28 |
---|---|
[CRUD] Delete : 글 삭제하기 (1) | 2023.11.27 |
[CRUD] Read : 글 읽기 (1) | 2023.11.23 |
[CRUD] Create : 글 쓰기 (0) | 2023.11.22 |
[CRUD] List : 목록 출력 (2) | 2023.11.21 |