프로젝트

가전제품 대여 웹사이트 (세숫대여) - 자유게시판 글 수정/삭제 기능 구현

sejin2 2023. 9. 29. 19:23

게시글 조회리스트에서 글 제목을 클릭하면 해당 글의 상세보기 페이지로 넘어가는데,  여기서 수정 삭제 기능을 구현해야 한다 !!

 먼저 수정 기능을 구현해본다.  첫번째로, 사용자가 볼 수 있는 게시글 수정 화면을 만들어야 한다.  

- src/main/webapp/WEB-INF/views/freeboard에 freeboardedit.jsp 생성

freeboardedit.jsp

<div class="row">
    <div class="col-xl-12 mb-5 mb-xl-0">
        <div class="card bg-secondary shadow">
            <div class="card-header border-0">
                <div class="row align-items-center">
                    <div class="col-8">
                        <h3 style="font-weight: bold" class="mb-0">자유게시글수정하기</h3>
                    </div>
                </div>
            </div>
            <div class="card-body">
                <form action="freeboardedit" method="post" enctype="multipart/form-data">
                    <input type="hidden" name="freeBoardNo" value="${ requestScope.freeBoard.freeBoardNo }"> 
                    <input type="hidden" name="pageNo" value="${ pageNo }">
                    <div class="pl-lg-4">
                        <div class="row">
                            <div class="col-lg-12">
                                <div class="form-group">
                                    <label style="font-size: 12pt" class="form-control-label" for="input-freeBoardTitle">제목</label> 
                                        <input type="text" id="input-freeBoardTitle" name="freeBoardTitle" class="form-control form-control-alternative"
                                        value="${ freeBoard.freeBoardTitle }" placeholder="제목을 입력하세요" />
                                </div>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-lg-12">
                                <div class="form-group">
                                    <label style="font-size: 12pt" class="form-control-label" for="input-memberNo">작성자</label> 
                                    ${ sessionScope.loginuser.memberId } <input type="hidden" id="input-memberNo" name="memberNo"
                                    class="form-control form-control-alternative"  value="${ loginuser.memberId }">
                                </div>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-lg-12">
                                <div class="form-group">
                                    <label style="font-size: 12pt" class="form-control-label" for="input-freeBoardAttach">첨부파일</label> <input type="file"
                                    id="attach" class="btn btn-sm btn-primary" class="form-control form-control-alternative" 
                                    name="attach" style="width: 200px">
                                    <td>
                                    <c:forEach var="freeBoardAttach" items="${ freeBoard.freeBoardAttachList }">
                                        <a href="download?attachNo=${ freeBoardAttach.attachNo }"> ${freeBoardAttach.attachFileName}</a>
                                    </c:forEach>
                                    </td>
                                </div>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-lg-12">
                                <div class="form-group">
                                    <label style="font-size: 12pt" class="form-control-label" for="input-freeBoardContent">글내용</label>
                                    <textarea name="freeBoardContent" id="input-freeBoardContent" style="resize: none;" rows="15"
                                    placeholder="내용을 입력하세요" class="form-control form-control-alternative">${ freeBoard.freeBoardContent }</textarea>
                                </div>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-lg-12">
                                <div class="col text-center">
                                    <input type="submit" class="btn btn btn-primary" value="수정하기"> 
                                    <input type="button" class="btn btn btn-primary" id="btnCancel" value="취소">
                                </div>
                            </div>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>

FreeBoardController.java

// 자유게시글 수정하기 ( 자유게시글 상세보기 내용 불러오기 )
    @GetMapping(path = {"/freeboardedit"})
    public String showFreeBoardEditForm(@RequestParam(defaultValue = "-1") int freeBoardNo, 
                                        @RequestParam(defaultValue = "-1") int pageNo,
                                        Model model) { 
        if (freeBoardNo == -1 || pageNo == -1) {
            return "redirect:freeboardlist";
        }

    FreeBoardDto freeboard = freeBoardService.findFreeBoardByFreeBoardNo(freeBoardNo);

        if (freeboard == null) {
            return "redirect:freeboardlist";
        } 
        
    model.addAttribute("freeBoard", freeboard);
    model.addAttribute("pageNo", pageNo);

    return "freeboard/freeboardedit";
} 
	// 자유게시글 수정하기 ( 수정한 글 등록하기 )
    @PostMapping(path = {"/freeboardedit"})
    public String freeBoardEdit(FreeBoardDto freeboard, MultipartFile attach, HttpServletRequest req,
                                @RequestParam(defaultValue = "-1") int pageNo) {

        if (pageNo < 1) {
            return "redirect:freeboardlist";
        } 
    // update 처리하기
    freeBoardService.editFreeBoard(freeboard); 
    return String.format("redirect:freeboarddetail?freeBoardNo=%d&pageNo=%d", freeboard.getFreeBoardNo(), pageNo);
}

FreeBoardService.java

void editFreeBoard(FreeBoardDto freeBoard);

FreeBoardServiceImpl.java

@Override   // 자유게시판 게시글 수정 내용 가지고 오기
	public void editFreeBoard(FreeBoardDto freeBoard) {
		freeboardMapper.updateFreeBoard(freeBoard); 
	}

FreeBoardMapper.java

@Update("update FreeBoard "
			+ "set freeBoardTitle = #{ freeBoardTitle }, freeBoardContent = #{ freeBoardContent } " // 자유게시판 게시글 수정하기 
			+ "where freeBoardNo = #{ freeBoardNo }")  
	void updateFreeBoard(FreeBoardDto freeBoard);

실행결과 화면 -> 수정하기 버튼을 누르면 수정페이지로 이동하고, 

아래 수정할 내용을 추가해 준 뒤 수정하기 버튼을 누르면,

수정이 잘 되는 것을 확인할 수 있다. 수정 페이지에서 취소 버튼을 누르면 다시 원래 상세보기 글로 가도록 연결해놓았다. 

 <script>
  window.addEventListener("load", function(event) {
  	const btnCancel = document.querySelector("#btnCancel");
  	btnCancel.addEventListener("click",function(event) { 
  		location.href="freeboardlist" +"?pageNo=" + ${pageNo};
  	});
  });
  </script>

다음은 삭제 기능을 구현해야하는데, SQL 문 작성 시에 데이터를 완전히 삭제하는게 아니라 DB에는 남기기 위해 DELETE 가 아니라 UPDATE로 처리할 것이다. 

FreeBoardController.java

// 자유게시글 삭제하기
@GetMapping(path = {"/freeboarddelete/{freeBoardNo}" })
public String freeBoardDelete(@PathVariable("freeBoardNo") int freeBoardNo,
                              @RequestParam(defaultValue = "-1") int pageNo) {

    if (pageNo == -1) {
        return "redirect:/freeboard/freeboardlist";
    }
    freeBoardService.deleteFreeBoard(freeBoardNo);
    return String.format("redirect:/freeboard/freeboardlist?pageNo=%d", pageNo);
}

FreeBoardService.java

void deleteFreeBoard(int freeBoardNo);

FreeBoardServiceImpl.java

@Override // 자유게시판 게시글 삭제 
public void deleteFreeBoard(int freeBoardNo) {
    freeboardMapper.deleteFreeBoard(freeBoardNo);
}

FreeBoardMapper.java

@Update("update FreeBoard "                                    
        + "set freeBoardDelete = true "
        + "where freeBoardNo = #{ freeBoardNo }")
void deleteFreeBoard(@Param("freeBoardNo") int freeBoardNo);

여기까지 한 후에 게시글을 삭제하면 리스트에 삭제된 글이라는 것을 사용자가 알 수 있도록 해준다. 

<table class="table align-items-center table-flush">
    <thead class="thead-light">
        <tr style="text-align: center;">
            <th scope="col" style="width: 100px; font-size: 10pt">게시글번호</th>
            <th scope="col" style="width: 500px; font-size: 10pt">게시글제목</th>
            <th scope="col" style="width: 200px; font-size: 10pt">작성자</th>
            <th scope="col" style="width: 100px; font-size: 10pt">조회수</th>
            <th scope="col" style="width: 150px; font-size: 10pt">게시글
                작성 일자</th>
        </tr>
    </thead>
    <tbody>
        <c:forEach var="freeBoard"
            items="${ requestScope.freeBoardList }">
            <tr style="text-align: center">
                <td scope="col" style="width: 100px">${ freeBoard.freeBoardNo }
                </td>
                <td scope="col" style="width: 500px">
                    <c:choose>
                        <c:when test="${ not freeBoard.freeBoardDelete }">
                            <a href="freeboarddetail?freeBoardNo=${ freeBoard.freeBoardNo }&pageNo=${ pageNo }"> ${ freeBoard.freeBoardTitle }</a>
                            <!-- 삭제 아닐때 그냥 제목 보이기 -->
                        </c:when>
                        <c:otherwise>
                            <span class="freeBoardDelete" style="color: gray"><<삭제된 게시글입니다 >></span>
                            <!-- 삭제된 글 화면 보이기 -->
                        </c:otherwise>
                    </c:choose>
                </td>
                <td scope="col" style="width: 200px">${ freeBoard.freeBoardDelete? '' : sessionScope.loginuser.memberId } <!-- 게시글 삭제시 작성자 안보이게 설정 --> 
                <input type="hidden" name="memberNo" value="${ loginuser.memberId }">
                <td scope="col" style="width: 100px">${ freeBoard.freeBoardViewCount }</td>
                <td scope="col" style="width: 150px"><fmt:formatDate value="${ freeBoard.freeBoardDate }" pattern="yyyy-MM-dd HH:mm" /></td>
            </tr>
        </c:forEach>
    </tbody>
</table>

 삭제하기 버튼을 누르면, 위에서 설정한 것처럼 보이는 것을 확인할 수 있다 .