-
[ Spring Boot + JPA + Thymeleaf ] 게시판 만들기 - 3Spring Boot 2021. 2. 10. 19:54
* 게시판 CRUD
저번 포스팅에서는 수동으로 내가 넣어논 데이터를 단순히 뿌려주기만 하는 기능을 구현해보았는데, 이번에는 내가 직접 글을 작성하고, 수정, 삭제까지 가능하도록 기능을 구현해보겠다.
우선 글 작성을 위한 페이지를 만들기위해 이번에도 역시 BootStrap에서 참고하여 레이아웃을 잡아주었다.
이제 글 작성 페이지로 넘겨주는 컨트롤러를 작성해야하는데, 이번에는 해당 페이지에서 폼을 전송하여 데이터를 저장해주는 작업이 필요하기 때문에 Board 객체를 생성해주었다.
// 내용 입력 폼 @GetMapping("/form") public String form(Model model){ // 신규 폼 model.addAttribute("board", new Board()); return "board/form"; }
그리고 form.html에서 submit을 해주면 내가 작성한 데이터를 Board객체로 넘겨받아 저장할 수 있다.
@Valid 애노테이션은 파라미터를 검증해주는 것인데, @Valid 어노테이션을 통해 유효한 객체인지 검사한 후 객체가 유효하지 않으면 bindingResult.hasErrors() 메소드에서 true 값이 반환된다.
// 내용 저장 @PostMapping("/form/save") public String saveForm(@Valid Board board, BindingResult result){ if (result.hasErrors()) { return "board/form"; } boardRepository.save(board); return "redirect:/board/list"; }
!! 위와같이 코드를 짜보니 오류가 났다. 해당 코드는 신규등록이랑 수정시 같이 사용되는 메서드인데 휴효성 체크를 하게되어 글 신규 작성시 id값이 null이라 오류가 나는것같다. if문을 삭제해주니 정상적으로 작동되었다.
그 다음으로 작성한 글을 수정하기 위해 우선 저장되어있는 데이터를 폼에 알맞게 뿌려주는 부분을 구현해볼것이다.
우선, 해당 게시물의 키값을 넘겨 주어야 데이터를 가져올 수 있기 때문에 th:href="@{/board/form(id=${board.id})}" 방식으로 id값을 넘겨 준 후 Controller에서
// 수정 시 내용 가져오기 Board board = boardRepository.findById(id).orElse(null); model.addAttribute("board", board);
위와같이 findById를 사용하여 데이터를 객체에 담아 준 후 form.html페이지로 넘겨주면 데이터가 알맞게 뿌려지는것을 볼 수 있다.
그리고 글 작성시와 동일하게 작동되는데 id값을 가지고 있으므로 자동으로 업데이트가 실행이 된다. 아주 편리하다.
해당 key값이 존재하면 업데이트, 없으면 신규생성이 된다. 하지만 내가 알기론 save()를 실행하면 select 후 insert 또는 update를 하는것이라 나중에 많은 데이터를 처리할 경우에는 불필요한 select시 속도가 느려질수도 있을거라는 생각이 든다..
이제 마지막으로 글 삭제 기능을 구현해보겠다.
위의 코드들과 딱히 다를것은 없고, deleteById()를 이용하여 데이터 삭제 기능을 구현해주면 된다.
삭제는 신중해야하므로? 스크립트로 확인창 한번 띄워주고 삭제하도록 구현했다.
- BoardController.java
package com.example.myhome.controller; import com.example.myhome.model.Board; import com.example.myhome.repository.BoardRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.validation.Valid; import java.util.List; @Controller @RequestMapping("/board") public class BoardController { @Autowired private BoardRepository boardRepository; // 리스트 출력 @GetMapping("/list") public String list(Model model){ List<Board> boards = boardRepository.findAll(); model.addAttribute("boards", boards); return "board/list"; } // 내용 입력 폼 @GetMapping("/form") public String form(Model model, @RequestParam(required = false) Long id){ if(id == null){ // 신규 폼 model.addAttribute("board", new Board()); }else{ // 수정 시 내용 가져오기 Board board = boardRepository.findById(id).orElse(null); model.addAttribute("board", board); } return "board/form"; } @PostMapping("/form/save") public String saveForm(@Valid Board board, BindingResult result){ boardRepository.save(board); return "redirect:/board/list"; } @PostMapping("/form/delete") public String deleteForm(@RequestParam(required = true) Long id){ boardRepository.deleteById(id); return "redirect:/board/list"; } }
- form.html
<!doctype html> <html xmlns:th="http://www.thymelef.org"> <head th:replace="fragments/common :: head('게시판')"> </head> <body> <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top" th:replace="fragments/common :: menu('list')"> </nav> <div class="container"> <h2>게시판</h2> <form name="globalform" action="#" th:action="@{/board/form}" th:object="${board}" method="post"> <input type="hidden" th:field="*{id}"> <div class="mb-3"> <label for="exampleFormControlInput1" class="foboardrm-label">제목</label> <input type="text" class="form-control" id="exampleFormControlInput1" th:field="*{title}"> </div> <div class="mb-3"> <label for="exampleFormControlTextarea1" class="form-label">내용</label> <textarea class="form-control" id="exampleFormControlTextarea1" rows="3" th:field="*{content}"></textarea> </div> <div class="text-right"> <a type="button" class="btn btn-primary" th:href="@{/board/list}">이전</a> <a type="submit" class="btn btn-primary" th:href="'javascript:saveForm('+*{id}+')'">저장</a> <a type="submit" class="btn btn-primary" th:href="'javascript:delForm('+*{id}+')'">삭제</a> </div> </form> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script> </body> <script> // 저장 function saveForm(id){ var frm = document.globalform; frm.action = "/board/form/save?id="+id; frm.method = "post"; frm.submit(); } // 삭제 function delForm(id){ if(confirm("삭제하시겠습니까?")){ var frm = document.globalform; frm.action = "/board/form/delete?id="+id; frm.method = "post"; frm.submit(); } } </script> </html>
- list.html
<!doctype html> <html xmlns:th="http://www.thymelef.org"> <head th:replace="fragments/common :: head('게시판')"> </head> <body> <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top" th:replace="fragments/common :: menu('list')"> </nav> <div class="container"> <h2>게시판</h2> <div>총 건수 : <span th:text="${#lists.size(boards)}"></span></div> <table class="table"> <thead> <tr> <th scope="col">번호</th> <th scope="col">제목</th> </tr> </thead> <tbody> <tr th:each="board : ${boards}"> <th th:text="${board.id}">1</th> <td><a th:text="${board.title}" th:href="@{/board/form(id=${board.id})}" >Mark</a></td> </tr> </tbody> </table> <div class="text-right"> <a type="button" class="btn btn-primary" th:href="@{/board/form}">글쓰기</a> </div> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script> </body> </html>
'Spring Boot' 카테고리의 다른 글
[ Spring Boot + JPA + Thymeleaf ] 페이징 기능 구현 (0) 2021.03.04 [ Spring Boot + JPA + Thymeleaf ] validation 추가 (0) 2021.03.02 [ Spring Boot + JPA + Thymeleaf ] 로그인/회원가입 (0) 2021.02.23 [ Spring Boot + JPA + Thymeleaf ] 게시판 만들기 - 2 (0) 2021.02.10 [ Spring Boot + JPA + Thymeleaf ] 게시판 만들기 - 1 (0) 2021.02.09