스프링 부트, 확장!

준비중..

스프링 부트, 확장!

댓글 기능 및 소셜 로그인!

23 댓글 등록하기

# 댓글 등록하기 ## 미션 --- 게시글에 댓글을 작성하고, ![클라우드스터딩-스프링부트-댓글-작성](https://i.imgur.com/BpTJIoC.png) 저장된 레코드를 확인하시오. ![클라우드스터딩-스프링부트-댓글-DB-레코드-확인](https://i.imgur.com/k4xqKjq.png) ## 개념 --- #### ⭐️ 진행 흐름 사용자가 댓글을 작성한다. 이를 JS에서 객체(JSON)로 만들고, Ajax로 전송. 이를 스프링 서버의 컨트롤러가 DTO로 변환하여 받는다. 컨트롤러는 데이터 저장 업무를 리파지터리에게 위임한다. 이 때, DTO가 Entity로 변환되고, Entity는 리파지터리에 의해 DB에 저장된다. 그 결과, 하나의 댓글 레코드가 만들어 진다. ![클라우드스터딩-스프링-부트-댓글-생성-과정](https://i.imgur.com/SBFgMl3.png) ## 튜토리얼 --- #### ⭐️ 뷰 페이지 1) 댓글 입력 창 만들기: "comments/_comments.mustache" ``` <div class="card" id="comments"> <div class="card-body"> <form> <div class="form-group"> <label>댓글 작성</label> <textarea class="form-control" id="comment-content" rows="3"></textarea> </div> <input type="hidden" id="comment-author" value="익명"> <button type="button" class="btn btn-primary" id="comment-create-btn">제출</button> </form> </div> </div> <!-- ajax 통신을 위한 JS 추가 --> <Script src="/js/app/comment.js"></script> ``` 2) 댓글 입력 창 추가: "articles/show.mustache" ``` ... <table class="table table-hover"> ... </table> <!-- 댓글 페이지 --> {{>comments/_comments}} <a href="/articles" class="btn btn-success btn-block">목록으로</a> <!-- ArticleJS for Ajax --> <Script src="/js/app/article.js"></script> {{>layouts/footer}} ``` #### ⭐️ JS 파일 3) 생성: "js/app/comment.js" ``` // 데이터 전송 객체 생성! var comment = { // 이벤트 등록 init: function() { var _this = this; // 생성 버튼 클릭 시! const createBtn = document.querySelector('#comment-create-btn'); // 이벤트 감시 시, 수행할 메소드 연결! createBtn.addEventListener('click', function(){ _this.create(); }); }, // 댓글 등록 create: function() { // 데이터 var data = { author: document.querySelector('#comment-author').value, content: document.querySelector('#comment-content').value, }; // url에서 article의 id를 추출! var split = location.pathname.split('/'); var articleId = split[split.length - 1]; // Ajax 통신 // - https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch // - https://t.ly/Vrrz fetch('/api/comments/' + articleId, { // 요청을 보냄 method: 'POST', body: JSON.stringify(data), headers: { 'Content-Type': 'application/json' } }).then(function(response) { // 응답 처리 if (response.ok) { // 성공 alert('댓글이 등록되었습니다.'); window.location.reload(); } else { // 실패 alert('댓글 등록 실패..!'); } }); } }; // 객체 초기화! comment.init(); ``` #### ⭐️ API 컨트롤러 4) 생성: "api/CommentApiController" ``` @Slf4j @RequiredArgsConstructor @RestController public class CommentApiController { private final CommentRepository commentRepository; @PostMapping("/api/comments/{articleId}") public Long create(@PathVariable Long articleId, @RequestBody CommentForm form) { log.info("form: " + form.toString()); Comment saved = commentRepository.save(form.toEntity()); log.info("saved: " + saved.toString()); return saved.getId(); } } ``` #### ⭐️ 리파지터리 인터페이스 5) 생성: "repository/CommentRepository" ``` public interface CommentRepository extends CrudRepository<Comment, Long> { } ``` #### ⭐️ DTO 6) 생성: "dto/CommentForm" ``` @Data public class CommentForm { private Long id; private String author; private String content; public Comment toEntity() { return Comment.builder() .id(id) .author(author) .content(content) .build(); } } ``` #### ⭐️ 엔티티 클래스 7) 기존 코드 확인: "entity/Comment" ``` @Getter @ToString @Builder @NoArgsConstructor // 디폴트 생성자 넣어 줌! @AllArgsConstructor // 모든 필드 포함 생성자 자동 기입 @Entity public class Comment extends BaseTime { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(length = 20, nullable = false) private String author; @Column(columnDefinition = "TEXT", nullable = false) private String content; } ``` #### ⭐️ 확인하기 8) 댓글 작성 ![클라우드스터딩-스프링부트-댓글-작성](https://i.imgur.com/BpTJIoC.png) 9) DB 레코드 확인 ![클라우드스터딩-스프링부트-댓글-DB-레코드-확인](https://i.imgur.com/k4xqKjq.png) ## 훈련하기 --- - 튜터리얼 중 댓글 생성 시 수행되는 SQL 쿼리를 분석하고, 이를 설명하시오. ## 면접 준비 --- - 입력한 댓글이 DB에 저장되기 까지의 과정? - 입력 댓글이 어떤 article에서 작성 되었는지, DB 레코드에서 확인 가능한가?