[Spring Boot] 11. Spring Boot Project (Blog v2 - jpa)_8.Board - Update

김미숙's avatar
Jul 22, 2025
[Spring Boot] 11. Spring Boot Project (Blog v2 - jpa)_8.Board - Update

BoardRequest

package shop.mtcoding.blog.board; import lombok.Data; import shop.mtcoding.blog.user.User; public class BoardRequest { @Data public static class SaveDTO { private String title; private String content; private String isPublic; public Board toEntity(User user) { return Board.builder() .title(title) .content(content) .isPublic(isPublic == null ? false : true) .user(user) // user 객체 필요 .build(); } } @Data public static class UpdateDTO { private String title; private String content; private String isPublic; } }

Board

package shop.mtcoding.blog.board; import jakarta.persistence.*; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import org.hibernate.annotations.CreationTimestamp; import shop.mtcoding.blog.reply.Reply; import shop.mtcoding.blog.user.User; import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; @NoArgsConstructor @Getter @Table(name = "board_tb") @Entity public class Board { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String title; private String content; private Boolean isPublic; @ManyToOne(fetch = FetchType.LAZY) private User user; // ORM @OneToMany(mappedBy = "board", fetch = FetchType.LAZY) // board = one , reply = many , mappedBy -> FK의 주인 @OneToMany -> 조회용도 private List<Reply> replies = new ArrayList<>(); //조회할 때만 넣기위함 @CreationTimestamp private Timestamp createdAt; @Builder public Board(Integer id, String title, String content, Boolean isPublic, User user, Timestamp createdAt) { this.id = id; this.title = title; this.content = content; this.isPublic = isPublic; this.user = user; this.createdAt = createdAt; } // 게시글 수정 Setter public void update(String title, String content, String isPublic) { this.title = title; this.content = content; this.isPublic = isPublic == null ? false : true; } }

BoardController

package shop.mtcoding.blog.board; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import shop.mtcoding.blog.user.User; @RequiredArgsConstructor @Controller public class BoardController { private final BoardService boardService; private final HttpSession session; @GetMapping("/") public String list(HttpServletRequest request) { User sessionUser = (User) session.getAttribute("sessionUser"); if (sessionUser == null) { request.setAttribute("models", boardService.글목록보기(null)); } else { request.setAttribute("models", boardService.글목록보기(sessionUser.getId())); } return "board/list"; } @PostMapping("/board/save") public String save(BoardRequest.SaveDTO saveDTO) { // 인증로직 User sessionUser = (User) session.getAttribute("sessionUser"); if (sessionUser == null) throw new RuntimeException("인증이 필요합니다."); boardService.글쓰기(saveDTO, sessionUser); return "redirect:/"; } @GetMapping("/board/save-form") public String saveForm() { return "board/save-form"; } @GetMapping("/board/{id}") public String detail(@PathVariable("id") Integer id, HttpServletRequest request) { User sessionUser = (User) session.getAttribute("sessionUser"); // 비로그인 시 상세보기 Integer sessionUserId = (sessionUser == null ? null : sessionUser.getId()); BoardResponse.DetailDTO detailDTO = boardService.글상세보기(id, sessionUserId); request.setAttribute("model", detailDTO); return "board/detail"; } @GetMapping("/board/{id}/update-form") public String updateForm(@PathVariable("id") Integer id, HttpServletRequest request) { // 인증로직 User sessionUser = (User) session.getAttribute("sessionUser"); if (sessionUser == null) throw new RuntimeException("인증이 필요합니다."); Board board = boardService.업데이트글보기(id, sessionUser.getId()); request.setAttribute("model", board); return "board/update-form"; } @PostMapping("/board/{id}/update") public String update(@PathVariable("id") Integer id, BoardRequest.UpdateDTO reqDTO) { // 인증로직 User sessionUser = (User) session.getAttribute("sessionUser"); if (sessionUser == null) throw new RuntimeException("인증이 필요합니다."); boardService.게시글수정(reqDTO, id, sessionUser.getId()); return "redirect:/board/" + id; } }

BoardService

package shop.mtcoding.blog.board; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import shop.mtcoding.blog._core.error.ex.Exception403; import shop.mtcoding.blog._core.error.ex.Exception404; import shop.mtcoding.blog.love.Love; import shop.mtcoding.blog.love.LoveRepository; import shop.mtcoding.blog.reply.Reply; import shop.mtcoding.blog.reply.ReplyRepository; import shop.mtcoding.blog.user.User; import java.util.List; @RequiredArgsConstructor @Service public class BoardService { private final BoardRepository boardRepository; private final LoveRepository loveRepository; private final ReplyRepository replyRepository; @Transactional public void 글쓰기(BoardRequest.SaveDTO saveDTO, User sessionUser) { Board board = saveDTO.toEntity(sessionUser); boardRepository.save(board); } public List<Board> 글목록보기(Integer userId) { return boardRepository.findAll(userId); } public BoardResponse.DetailDTO 글상세보기(Integer id, Integer userId) { Board board = boardRepository.findByIdJoinUser(id); Love love = loveRepository.findByUserIdAndBoardId(userId, id); Boolean isLove = love == null ? false : true; Integer loveId = love == null ? null : love.getId(); Long loveCount = loveRepository.findByBoardId(board.getId()); List<Reply> replies = replyRepository.findAllByBoardId(id); BoardResponse.DetailDTO detailDTO = new BoardResponse.DetailDTO(board, userId, isLove, loveCount.intValue(), loveId, replies); return detailDTO; } public Board 업데이트글보기(Integer id, Integer sessionUserId) { Board boardPs = boardRepository.findById(id); if (boardPs == null) throw new RunTimeException("게시글을 찾을 수 없습니다."); if (!boardPs.getUser().getId().equals(sessionUserId)) throw new RunTimeException("권한이 없습니다."); return boardPs; } @Transactional public Board 게시글수정(BoardRequest.UpdateDTO reqDTO, Integer id, Integer sessionUserId) { Board board = boardRepository.findById(id); if (board == null) throw new RunTimeException("게시글을 찾을 수 없습니다"); if (!board.getUser().getId().equals(sessionUserId)) throw new RunTimeException("권한이 없습니다."); board.update(reqDTO.getTitle(), reqDTO.getContent(), reqDTO.getIsPublic()); return board; } }

update-form

{{> layout/header}} <div class="container p-5"> <div class="card"> <div class="card-header"><b>글수정하기 화면입니다</b></div> <div class="card-body"> <form action="/board/{{model.id}}/update" method="post"> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter title" name="title" value="{{model.title}}"> </div> <div class="mb-3"> <textarea class="form-control" rows="5" name="content">{{model.content}}</textarea> </div> <!-- ✅ 공개 여부 체크박스 --> <div class="form-check mb-3"> {{#model.isPublic}} <input class="form-check-input" type="checkbox" name="isPublic" checked value="true"> {{/model.isPublic}} {{^model.isPublic}} <input class="form-check-input" type="checkbox" name="isPublic" value="true"> {{/model.isPublic}} <label class="form-check-label" for="isPublic"> 공개 글로 작성하기 </label> </div> <button type="submit" class="btn btn-primary form-control">글수정하기완료</button> </form> </div> </div> </div> {{> layout/footer}}
ssar login → 게시글 5번 수정
notion image
notion image
notion image
수정
notion image
notion image
notion image
notion image
Share article

parangdajavous