

오늘 만들 것
이번 글에서는 게시판 구현의 마지막 단계인 게시글 삭제를 구현합니다.
게시글 삭제는 두 가지 방법을 사용할 수 있습니다.
실제로 DB에서 삭제하거나 삭제 표기를 하는 방법입니다.
이번 글에서는 주로 사용되는 방법인 삭제 표기를 진행합니다.
시작
이번 글은 Lab06의 코드에 기능을 추가하는 방식으로 진행합니다.
Lab06는 이전 글에서 확인할 수 있습니다.
별도의 프로젝트에서 진행하고자 하면, Lab06과 동일하게 프로젝트를 생성한 뒤 코드를 복사해서 준비합니다.
Lab06의 코드를 그대로 사용한다면 아래 예제 코드의 패키지명에 유의합니다.
아래 예제 코드는 별도의 프로젝트를 생성하는 방식으로 진행합니다.
SQL Mapper 수정
다음 경로의 파일을 아래와 같이 편집합니다: /src/main/resources/mappers/UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="net.jetalab.spreinglab08.dao.BoardDAO"> <insert id="newBoard" parameterType="net.jetalab.spreinglab08.dto.BoardDTO" useGeneratedKeys="true" keyProperty="seq"> INSERT INTO lab08(`title`, `contents`, `author`, `password`) VALUES (#{title}, #{contents}, #{author}, #{password}) </insert> <select id="getBoard" parameterType="net.jetalab.spreinglab08.dto.BoardDTO" resultType="net.jetalab.spreinglab08.dto.BoardDTO"> SELECT `seq`, `title`, `contents`, `author`, `reads` FROM lab08 WHERE `seq` = #{seq} <if test="password != null"> AND `password` = #{password} </if> AND `deleted` = 'N' </select> <update id="editBoard" parameterType="net.jetalab.spreinglab08.dto.BoardDTO"> UPDATE lab08 SET `password` = `password` <if test="title != null"> , `title` = #{title} </if> <if test="contents != null"> , `contents` = #{contents} </if> <if test="author != null"> , `author` = #{author} </if> <if test="deleted != null"> , `deleted` = #{deleted} </if> WHERE `seq` = #{seq} </update> </mapper>
<update id="editBoard" />
가 수정되었습니다.
23번째 줄 ~ 35번째 줄: password
는 변경되지 않기에 그대로 두고, 변경이 요구된 항목만 변경되도록 설정합니다. 이렇게 구성하면 UserDTO
에 값이 존재하는 항목만 UPDATE
되도록 활용할 수 있고, 의도치 않은 데이터 손실을 피할 수 있습니다./p>
Controller 생성
DELETE
로 삭제할 글의 ID와 그 글의 암호를 받을 Controller를 생성합니다.
다음 경로에 아래 코드를 작성하여 저장합니다: /src/main/java/YOUR/DOMAIN/ARTIFACT/controller/BoardController.java
package net.jetalab.spreinglab08.controller; import net.jetalab.spreinglab08.dao.BoardDAO; import net.jetalab.spreinglab08.dto.BoardDTO; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController @EnableAutoConfiguration @MapperScan(basePackages = "net.jetalab.spreinglab08.dao") public class BoardController { @Autowired private BoardDAO boardDAO; @RequestMapping(value = "/board", method = RequestMethod.POST) public ResponseEntity<BoardDTO> postBoard(BoardDTO board) throws Exception { if ((board.getAuthor() == null) || (board.getContents() == null) || (board.getPassword() == null) || (board.getTitle() == null)) { return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } boardDAO.newBoard(board); return new ResponseEntity<>(board, HttpStatus.OK); } @RequestMapping(value = "/board/{seq}", method = RequestMethod.GET) public ResponseEntity<BoardDTO> getBoard(@PathVariable("seq") final int seq) throws Exception { BoardDTO param = new BoardDTO(); param.setSeq(seq); /* TODO: 조회수 증가 */ BoardDTO board = boardDAO.getBoard(param); if (board == null) return new ResponseEntity<>(HttpStatus.NOT_FOUND); else return new ResponseEntity<>(board, HttpStatus.OK); } @RequestMapping(value = "/board/{seq}", method = RequestMethod.PUT) public ResponseEntity<BoardDTO> putBoard(@PathVariable("seq") final int seq, BoardDTO param) throws Exception { if ((param.getAuthor() == null) || (param.getContents() == null) || (param.getPassword() == null) || (param.getTitle() == null)) { return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } param.setSeq(seq); // 조회할 게시물 번호 지정 BoardDTO board = boardDAO.getBoard(param); if (board == null) return new ResponseEntity<>(HttpStatus.NOT_FOUND); board.setTitle(param.getTitle()); board.setContents(param.getContents()); board.setAuthor(param.getAuthor()); boardDAO.editBoard(board); return new ResponseEntity<>(board, HttpStatus.OK); } @RequestMapping(value = "/board/{seq}", method = RequestMethod.DELETE) public ResponseEntity<BoardDTO> deleteBoard(@PathVariable("seq") final int seq, BoardDTO param) throws Exception { if (param.getPassword() == null) { return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } param.setSeq(seq); // 조회할 게시물 번호 지정 BoardDTO board = boardDAO.getBoard(param); if (board == null) return new ResponseEntity<>(HttpStatus.NOT_FOUND); board.setDeleted("Y"); boardDAO.editBoard(board); return new ResponseEntity<>(HttpStatus.OK); } }
DELETE /board/{seq}
가 추가되었습니다.
66번째 줄 ~ 68번째 줄: password
가 없다면 올바르지 않은 요청으로 보고 오류를 반환합니다.
74번째 줄: 만약 조회된 게시물이 있다면 deleted
플래그를 삭제된 것으로 지정합니다.
테스트
먼저 삭제할 글을 호출해봅니다.

이제 삭제할 글 번호와 비밀번호를 입력해서 삭제를 요청해봅니다.
이 때, 만약 비밀번호가 틀리면 오류를 반환합니다.

비밀번호가 올바르다면 정상적으로 처리됩니다.

이제 게시글을 다시 호출하면 404 오류가 반환됩니다.


DB에도 삭제된 상태가 지정되어 있습니다.

예제 코드
본 포스트의 예제 코드는 GitHub에 공개되어 있습니다.
https://github.com/jETA-Kor/sp-re-ing/tree/master/lab08
댓글을 사용할 수 없습니다.