Spring Boot

[게시판 만들기 (6)] 게시글 수정

서윤-정 2024. 1. 14. 11:52

 

[ detail.html ]

<button onclick="listReq()">목록</button>
<button onclick="updateReq()">수정</button>
<button onclick="deleteReq()">삭제</button>

</body>
<script th:inline="javascript">
    const updateReq = () => {
        console.log("수정 요청");
        const id = [[${board.id}]];
        location.href = "/board/update/" + id;
    }
</script>

 

th:inline="javascript": 시작해야 타임리프의 자바스크립트 인라인 모드를 활성화 할 수 있다.

updateReq() 함수: "수정 요청"을 콘솔에 출력하고, 

현재 게시글의 ID를 사용하여 '/board/update/{id}" 엔드포인트로 페이지 이동하는 함수이다.

const id = [[${board.id}]] 를 통해 타임리프의 표현식을 사용하여 서버에서 전달된 게시글의 ID를 가져왔다. 

[[${board.id}]]: 타임리프 표현식을 사용하여 서버에서 전달된 게시글의 ID를 동적으로 삽입한다.

() => {...}: 매개변수가 없는 경우 ( )는 비워둘 수 있다. 

중괄호 {...} 안에는 함수의 몸체가 위치한다.

 

 

 

 

 

 

 

 

 

 

 

글수정은 아래의 단계로 이루어진다.

1. 상세화면에서 수정 버튼 클릭

2. 서버에서 해당 게시글의 정보를 가지고 수정 화면 출력

3. 제목, 내용 수정 입력 받아서 서버로 요청

4. 수정 처리

 

 

 

BoardController 클래스에 updateForm 메서드와 update 메서드를 추가한다.

updateForm 메서드는 update.html 로 이동하는 역할이고,

update 메서드는 데이터 업데이트를 수행하는 역할이다.

    @GetMapping("/update/{id}")
    public String updateForm(@PathVariable Long id, Model model) {
        BoardDTO boardDTO = boardService.findById(id);
        model.addAttribute("boardUpdate", boardDTO);
        return "update";
    }

    @PostMapping("/update")
    public String update(@ModelAttribute BoardDTO boardDTO, Model model) {
        BoardDTO board = boardService.update(boardDTO);
        model.addAttribute("board", board);
        return "detail";
//        return "redirect:/board/" + boardDTO.getId();
    }

 

<updateForm 메서드>

@PathVariable: URL에서 받아온 id 값을 메소드의 매개변수로 받는다.

 

BoardDTO boardDTO = boardService.findById(id);

 

해당 id에 해당하는 게시글을 조회하여 BoardDTO 객체로 받아준다.

 

model.addAttribute("boardUpdate", boardDTO);

조회한 게시글 정보를 boardUpdate 라는 이름으로 모델에 추가한다.

 

<update 메서드>

@ModelAttribute BoardDTO boardDTO

요청의 바디에서 전달된 데이터를 BoardDTO 객체로 받는다.

 

BoardDTO board = boardService.update(boardDTO);

받아온 데이터를 사용하여 게시글을 업데이트하고, 업데이트된 정보를 BoardDTO 형태로 받아온다.

 

model.addAttribute("board", board);

업데이트 된 게시글 정보를 board 라는 이름으로 모델에 추가한다.

 

 

 

 

 

 

 

 

 

 

BoardService 클래스에 update 메서드를 추가한다.

 

[ BoardService ]

// spring data jpa는 따로 update를 위한 메서드는 없음.
// save 가지고 업데이트, 인서트도 함.
// 업데이트, 인서트를 구분하는 기준은 id 값의 유무
public BoardDTO update(BoardDTO boardDTO) {
    BoardEntity boardEntity = BoardEntity.toUpdateEntity(boardDTO);
    boardRepository.save(boardEntity);
    return findById(boardDTO.getId());
}

 

  BoardEntity boardEntity = BoardEntity.toUpdateEntity(boardDTO);

BoardDTO 객체를 BoardEntity 객체로 변환한다. 

이때, BoardEntity.toUpdateEntity 메서드를 사용하여 엔티티를 생성한다.

이 메서드는 주어진 BoardDTO 에서 필요한 정보를 추출하여 새로운 BoardEntity 객체를 생성한다.

 

boardRepository.save(boardEntity);

spring data jpa에서 제공하는 save 메서드를 사용하여 BoardEntity 를 저장한다. 

이 메서드는 주어진 엔티티가 이미 데이터베이스에 존재하면 업데이트를, 

존재하지 않으면 인서트를 수행한다.

 

return findById(boardDTO.getId());

업데이트가 완료된 후, 업데이트된 게시글의 정보를 조회하기 위해 findById 메서드를 호출하여

해당 id에 해당하는 게시글을 다시 가져온다. 

그리고 이를 BoardDTO 형태로 반환한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

BoardEntity 엔티티에 toUpdateEntity를 추가한다.

BoardDTO를 BoardEntity로 변환하는 역할을 한다.

 

[ BoardEntity ]

public static BoardEntity toUpdateEntity(BoardDTO boardDTO) {
    BoardEntity boardEntity = new BoardEntity();
    // id가 있어야 update 쿼리 전달 가능
    boardEntity.setId(boardDTO.getId());
    boardEntity.setBoardWriter(boardDTO.getBoardWriter());
    boardEntity.setBoardPass(boardDTO.getBoardPass());
    boardEntity.setBoardTitle(boardDTO.getBoardTitle());
    boardEntity.setBoardContents(boardDTO.getBoardContents());
    boardEntity.setBoardHits(boardDTO.getBoardHits());
    return boardEntity;
}

 

 

 

 

 

 

 

 

 

템플릿 패키지에 update.html 도 생성한다.

 

[ update.html ]

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>update</title>
</head>
<body>
<form action="/board/update" method="post" name="updateForm">
    <input type="hidden" name="id" th:value="${boardUpdate.id}">
    writer: <input type="text" name="boardWriter" th:value="${boardUpdate.boardWriter}" readonly> <br>
    pass: <input type="text" name="boardPass" id="boardPass"> <br>
    title: <input type="text" name="boardTitle" th:value="${boardUpdate.boardTitle}"> <br>
    contents: <textarea name="boardContents" cols="30" rows="10" th:text="${boardUpdate.boardContents}"></textarea> <br>
    <input type="hidden" name="boardHits" th:value="${boardUpdate.boardHits}">
    <input type="button" value="글수정" onclick="boardUpdate()">
</form>
<script th:inline="javascript">
    const boardUpdate = () => {
        const pass = [[${boardUpdate.boardPass}]];
        const inputPass = document.getElementById("boardPass").value;
        if (pass == inputPass) {
            document.updateForm.submit();
        } else {
            alert("비밀번호가 일치하지 않습니다!");
        }
    }
</script>
</body>

 

const pass = [[${boardUpdate.boardPass}]];

타임리프 템플릿 문법을 사용하여 서버에서 전달받은 boardUpdate 객체의 boardPass 속성을 가져와서 

자바스크립트 변수 pass에 할당한다. (비밀번호)

 

const inputPass = document.getElementById("boardPass").value;

폼에서 id가 boardPass인 엘리먼트를 찾아서 해당 엘리먼트의 값을 inputPass 변수에 할당한다.

이는 사용자가 입력한 비밀번호를 가져오는 부분이다.

 

 

if (pass == inputPass) {

서버에서 가져온 boardPass 와 사용자가 입력한 inputPass를 비교한다.

 

document.updateForm.submit();

만약 비밀번호가 일치하면, HTML 문서에서 updateForm이라는 폼을 찾아 제출한다.

 

비밀번호가 일치하지 않을 경우 경고창을 띄운다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

이제 실행해보자!

 

수정 버튼을 클릭한다.

 

 

 

 

 

http://localhost:8092/board/update/1

정보가 잘 받아와졌다.

 

 

 

 

 

 

 

비밀번호를 다르게 입력하면 경고창이 뜬다.

 

 

 

 

 

비밀번호를 잘 입력하고 수정을 한다.

writer은 readonly여서 입력되지 않는다.

 

 

 

 

 

완료!