[Spring Boot] 11. Spring Boot Project (Blog v2 - jpa)_4.Board - Save

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

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, cascade = CascadeType.ALL, orphanRemoval = true) // 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; } }
 

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) // 공개 check -> true, check X -> false .user(user) // user 객체 필요 .build(); } } }

BoardController

package shop.mtcoding.blog.board; 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.PostMapping; import shop.mtcoding.blog.user.User; @RequiredArgsConstructor @Controller public class BoardController { private final BoardService boardService; private final HttpSession session; @GetMapping("/") public String home() { 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() { // 인증로직 User sessionUser = (User) session.getAttribute("sessionUser"); if (sessionUser == null) throw new RuntimeException("인증이 필요합니다."); return "board/save-form"; } }

BoardService

package shop.mtcoding.blog.board; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import shop.mtcoding.blog.user.User; @RequiredArgsConstructor @Service public class BoardService { private final BoardRepository boardRepository; @Transactional public void 글쓰기(BoardRequest.SaveDTO saveDTO, User sessionUser) { Board board = saveDTO.toEntity(sessionUser); boardRepository.save(board); } }

BoardRepository

package shop.mtcoding.blog.board; import jakarta.persistence.EntityManager; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @RequiredArgsConstructor @Repository public class BoardRepository { private final EntityManager em; public void save(Board board) { em.persist(board); } }

save-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/save" method="post"> <div class="mb-3"> <input type="text" class="form-control" placeholder="Enter title" name="title"> </div> <div class="mb-3"> <textarea class="form-control" rows="5" name="content"></textarea> </div> <!-- ✅ 공개 여부 체크박스 --> <div class="form-check mb-3"> <input class="form-check-input" type="checkbox" name="isPublic" checked> <label class="form-check-label" for="isPublic"> 공개 글로 작성하기 </label> </div> <button class="btn btn-primary form-control">글쓰기완료</button> </form> </div> </div> </div> {{> layout/footer}}

User ‘ssar’로 로그인해서 글 작성

➡ User ‘ssar’ login
notion image

login query

notion image
➡ 게시글 작성 / 공개 글 check
notion image
notion image
➡ 게시글 작성 / 공개 글 check X
notion image
notion image

insert query

notion image
Share article

parangdajavous