728x90
Spring - 게시판 만들기 연습 (게시물 삭제를 delete 대신 update처리)
DB에서 게시글을 삭제처리하면 기본키인 index도 함께 삭제된다. 그렇게 되면 기본키를 시퀀스Sequence로 설정했기 때문에 중간에 삭제된 index는 다시 채워지지않는다. 그렇게 되면 게시글의 갯수와 index의 숫자가 일치하지 않게된다. 만약 게시글의 숫자와 index로 연산을 해야되는 상황이 생긴다면 문제가 발생할 수도 있다. 그렇기 때문에 게시글을 DB에서 삭제처리하지 않고 상태를 변경시켜 목록에서는 보이지 않거나, 삭제된 게시글이라고 표시해주는게 좋다.
소스코드 변경 사항
Model(DB연동 작업처리)
01. boardVO에서 show 추가
public class BoardVO {
private int bno; // 게시글 번호
private String title; // 게시글 제목
private String content; // 게시글 내용
private String writer; // 게시글 작성자
private String userName; // 게시글 작성자의 이름(회원이름)
private Date regdate; // 게시글 작성일자 util.Date
private int viewcnt; // 게시글 조회수
private int recnt; // 게시글 댓글의 수
private String show; // *추가 - 게시글 삭제 상태 유무(y, n)
//Getter/Setter, toString() 생략...
}
02. boardMapper.xml에서 게시글 삭제 delete쿼리를 update쿼리로 변경
기존의 delete쿼리
<!-- 게시물을 DB에서 영국 삭제처리 -->
<delete id="deleteArticle">
DELETE FROM tbl_board WHERE bno = #{bno}
</delete>
변경된 update쿼리
<!-- 게시물을 삭제처리하지 않고, 삭제의 유무 상태만 변경 -->
<update id="deleteArticle">
UPDATE tbl_board SET show = 'n' WHERE bno = #{bno}
</update>
03. boardMapper.xml에서 게시글 목록 select쿼리 변경
show 칼럼 추가
<select id="listAll" resultType="com.example.spring02.model.board.dto.BoardVO">
<!-- 페이지 나누기를 포함한 게시글 목록쿼리 -->
<!-- 페이징 include-->
<include refid="pagingHeader"></include>
SELECT ROWNUM, bno, title, content, b.regdate, viewcnt, user_name AS userName, show, (SELECT COUNT(*) FROM tbl_reply WHERE bno=b.bno) AS recnt
FROM tbl_board b, tbl_member m
<!-- 검색조건 -->
<include refid="search"></include>
ORDER BY bno DESC, b.regdate DESC
<!-- 페이징 inclede-->
<include refid="pagingFooter"></include>
</select>
04. boardMapper.xml에서 게시글 입력 insert쿼리 변경
게시글 입력시 show칼럼에 기본값으로 ‘y’를 세팅
<insert id="insert">
INSERT INTO tbl_board (
bno, title, content, writer, show
) VALUES (
(SELECT NVL(MAX(bno)+1, 1)FROM tbl_board), #{title}, #{content}, #{writer}, 'y'
)
</insert>
05. boardMapper.xml에서 게시글 상세보기 select쿼리 변경
show 칼럼 추가
<!--03. 게시글 상세보기 조회 -->
<select id="view" resultType="com.example.spring02.model.board.dto.BoardVO">
<!-- SELECT * FROM tbl_board -->
SELECT
bno, title, content, b.regdate, writer, viewcnt, user_name AS userName, show
FROM
tbl_board b, tbl_member m
WHERE
b.writer = m.user_id
AND
bno = #{bno}
</select>
View(화면)
01. list.jsp(게시글 목록 화면)
show컬럼이 y일 때(삭제상태가 아닐때)는 원래 게시물의 레코드를 보여준다.
show컬럼이 n일 때(삭제상태일 때) “삭제된 게시물입니다”라는 문구를 출력해준다.
삭제된 게시글에 댓글이 존재하면 댓글의 숫자를 출력하고, 댓글로 이동하기 위해 하이퍼링크로 연결한다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게시글 목록</title>
<!--스크립트 생략....-->
</head>
<body>
<%@ include file="../include/menu.jsp" %>
<h2>게시글 목록</h2>
<form name="form1" method="post" action="${path}/board/list.do">
<select name="searchOption">
<option value="all" <c:out value="${map.searchOption == 'all'?'selected':''}"/> >제목+이름+제목</option>
<option value="user_name" <c:out value="${map.searchOption == 'user_name'?'selected':''}"/> >이름</option>
<option value="content" <c:out value="${map.searchOption == 'content'?'selected':''}"/> >내용</option>
<option value="title" <c:out value="${map.searchOption == 'title'?'selected':''}"/> >제목</option>
</select>
<input name="keyword" value="${map.keyword}">
<input type="submit" value="조회">
<c:if test="${sessionScope.userId != null}">
<button type="button" id="btnWrite">글쓰기</button>
</c:if>
</form>
${map.count}개의 게시물이 있습니다.
<table border="1" width="600px">
<tr>
<th>번호</th>
<th>제목</th>
<th>이름</th>
<th>작성일</th>
<th>조회수</th>
</tr>
<c:forEach var="row" items="${map.list}">
<c:choose>
<c:when test="${row.show == 'y'}">
<!-- show 컬럼이 y일때(삭제상태가 아닐때) -->
<tr>
<td>${row.bno}</td>
<!-- 게시글 상세보기 페이지로 이동시 게시글 목록페이지에 있는 검색조건, 키워드, 현재페이지 값을 유지하기 위해 -->
<td>
<a href="${path}/board/view.do?bno=${row.bno}&curPage=${map.boardPager.curPage}&searchOption=${map.searchOption}&keyword=${map.keyword}">${row.title}
<!-- ** 댓글이 있으면 게시글 이름 옆에 출력하기 -->
<c:if test="${row.recnt > 0}">
<span style="color: red;">(${row.recnt})
</span>
</c:if>
</a>
</td>
<td>${row.userName}</td>
<td>
<fmt:formatDate value="${row.regdate}" pattern="yyyy-MM-dd HH:mm:ss"/>
</td>
<td>${row.viewcnt}</td>
</tr>
</c:when>
<c:otherwise>
<!-- show 컬럼이 n일때(삭제된 상태일 때) -->
<tr>
<td colspan="5" align="left">
<c:if test="${row.recnt > 0}">
<a href="${path}/board/view.do?bno=${row.bno}&curPage=${map.boardPager.curPage}&searchOption=${map.searchOption}&keyword=${map.keyword}">
삭제된 게시물입니다.
<!-- ** 댓글이 있으면 게시글 이름 옆에 출력하기 -->
<span style="color: red;">(${row.recnt})
</span>
</a>
</c:if>
<c:if test="${row.recnt == 0 }">
삭제된 게시물입니다.
</c:if>
</td>
</tr>
</c:otherwise>
</c:choose>
</c:forEach>
<!-- 페이징 생략...-->
</table>
</body>
</html>
02. view.jsp(게시글 상세보기 화면)
show칼럼이 y이면(삭제상태가 아닐 때)는 원래 게시물의 레코드를 보여준다.
show칼럼이 n이면(삭제상태일 때)는 ‘삭제된 게시물입니다’라는 문구를 출력한다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>게시글 작성</title>
<!-- 스크립트, css 생략... -->
</head>
<body>
<%@ include file="../include/menu.jsp" %>
<h2>게시글 보기</h2>
<c:choose>
<c:when test="${dto.show == 'y'}">
<!-- show가 y면(삭제상태가 아닐 때) -->
<!-- 게시물 상세보기 영역 -->
<form name="form1" method="post">
<div>
작성일자 : <fmt:formatDate value="${dto.regdate}" pattern="yyyy-MM-dd a HH:mm:ss"/>
</div>
<div>
조회수 : ${dto.viewcnt}
</div>
<div>
제목
<input name="title" id="title" size="80" value="${dto.title}" placeholder="제목을 입력해주세요">
</div>
<div>
내용
<textarea name="content" id="content" rows="4" cols="80" placeholder="내용을 입력해주세요">${dto.content}</textarea>
</div>
<div>
이름
<%-- <input name="writer" id="writer" value="${dto.writer}" placeholder="이름을 입력해주세요"> --%>
${dto.userName}
</div>
<div style="width:650px; text-align: center;">
<input type="hidden" name="bno" value="${dto.bno}">
<c:if test="${sessionScope.userId == dto.writer}">
<button type="button" id="btnUpdete">수정</button>
<button type="button" id="btnDelete">삭제</button>
</c:if>
<button type="button" id="btnList">목록</button>
</div>
</form>
<div style="width:650px; text-align: center;">
<br>
<c:if test="${sessionScope.userId != null}">
<textarea rows="5" cols="80" id="replytext" placeholder="댓글을 작성해주세요"></textarea>
<br>
<input type="checkbox" id="secretReply">비밀 댓글
<button type="button" id="btnReply">댓글 작성</button>
</c:if>
</div>
</c:when>
<c:otherwise>
<!-- show가 n이면(삭제상태일 때) -->
삭제된 게시글 입니다.
</c:otherwise>
</c:choose>
<!-- 댓글 목록 영역 -->
<div id="listReply"></div>
<!-- 댓글 목록 영역 -->
</body>
</html>