오늘은 부트캠프 46일차이면서 프로젝트 2일차이다. 오전에는 내가 맡은 게시글과 댓글에 좋아요 기능을 구현하고, 누른 사람이 다시 누르면 취소되는 기능을 구현하는 것이다. 기존에 회원가입과 로그인은 강의에서 배우면서 실습도 하였지만, 내가 맡은 기능은 처음해보는 것이라서 난항을 겪었다. 처음 어떻게 코드를 짜야할까부터 다른 팀원들과 작업물을 Git을 통해 합치다 오류가 나오는 것까지 지금까지 한 것 중에 가장 난감하면서도 당황을 많이했다. 아쉬운 점은 내가 만약 테스트 코드를 작성을 할 줄 알았다면 미리 테스트를 해보면 훨씬 좋았을텐데 그 점이 너무 아쉬웠다.
오늘 배운 것
1.LikeController@RestController @RequiredArgsConstructor @RequestMapping("/api/likes") public class LikeController { private final PostLikeService postLikeService; private final CommentLikeService commentLikeService; //게시글 좋아요 @PostMapping("/post/{postId}") public ResponseEntity<MsgResponseDto> savePostLike( @PathVariable Long postId, @AuthenticationPrincipal UserDetailsImpl userDetails) { return ResponseEntity.ok().body(postLikeService.savePostLike(postId, userDetails.getUser())); } //댓글 좋아요 @PostMapping("/comment/{commentId}") public ResponseEntity<MsgResponseDto> commentLike(@PathVariable Long commentId, @AuthenticationPrincipal UserDetailsImpl userDetails) { return ResponseEntity.ok(commentLikeService.CommentLike(commentId, userDetails.getUser())); } }
2.CommentLike
@AllArgsConstructor @Getter @Entity @Builder @NoArgsConstructor public class CommentLike { //필드 @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long CommentLikeId; //commentLike : comment 관계 --> 다대일 단방향 관계 @ManyToOne @JoinColumn(name = "comment_id") //테이블에서 name 속성을 따로 적어주지 않는 경우, name 은 해당 객체명이 된다. private Comment comment; //commentLike : user 관계 --> 다대일 단방향 관계 @ManyToOne @JoinColumn(name = "comment_like_User_id") //테이블에서 name 속성을 따로 적어주지 않는 경우, name 은 해당 객체명이 된다. private User user; }
3.PostLike
@Getter @Entity @NoArgsConstructor public class PostLike { //필드 @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; //boardLikeList : board 관계 --> 다대일 양방향 관계 @ManyToOne @JoinColumn(name = "post_id", nullable = false) private Post post; @ManyToOne @JoinColumn(name = "user_id", nullable = false) private User user; //생성자 public PostLike(Post post, User user) { this.post = post; this.user = user; } }
- LikeService
@Service @RequiredArgsConstructor public class LikeService { // private final CommentRepository commentRepository; TODO : 추후 수정 예정 private final PostRepository postRepository; private final CommentLikeRepository commentLikeRepository; private final PostLikeRepository postLikeRepository; //댓글 좋아요 @Transactional public MsgResponseDto CommentLike(Long commentId, User user) { //DB 에서 댓글을 찾아봄 Comment comment = commentRepository.findById(commentId).orElseThrow( () -> new IllegalArgumentException("찾는 댓글이 없습니다.") ); //DB 에 해당 user 가 '댓글 좋아요' 누른 적이 없다면, '댓글 좋아요' 를 추가하기 if (commentLikeRepository.findByCommentIdAndUserId(commentId, Long.valueOf(user.getUsername())).isEmpty()){ CommentLike commentLike = CommentLike.builder() .comment(comment) .user(user) .build(); commentLikeRepository.save(commentLike); return new MsgResponseDto("좋아요 완료", HttpStatus.OK.value()); //DB 에 해당 user 가 '댓글 좋아요' 누른 적이 있다면, '댓글 좋아요' 를 제거하기 }else { commentLikeRepository.deleteByCommentIdAndUserId(comment.getId(), Long.valueOf(user.getUsername())); return new MsgResponseDto("좋아요 취소", HttpStatus.OK.value()); } } // 게시글 좋아요 확인 @Transactional(readOnly = true) public boolean checkPostLike(Long postId, User user) { return postLikeRepository.existsByPostIdAndUserId(postId, Long.valueOf(user.getUsername())); } // 게시글 좋아요 생성 및 삭제 @Transactional public MsgResponseDto savePostLike(Long postId, User user) { Post post = postRepository.findById(postId).orElseThrow( () -> new IllegalArgumentException("찾는 게시글이 없습니다.") ); if (!checkPostLike(postId, user)) { postLikeRepository.saveAndFlush(new PostLike(post, user)); return new MsgResponseDto("좋아요 완료", HttpStatus.OK.value()); } else { postLikeRepository.deleteByPostIdAndUserId(postId, Long.valueOf(user.getUsername())); return new MsgResponseDto("좋아요 취소", HttpStatus.OK.value()); } } }