일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- java list 저장
- 격파르타합격후기
- java기본자료형
- 노베이스부트캠프
- 격파르타장점
- javaJRE
- java최솟값구하기
- java 자료구조 활용
- javaJVM
- 항해99후기
- java list 출력
- java알고리즘
- 인터프린터언어
- java set 저장
- java map 저장
- 프로그래머스제일작은수
- 격파르타후기
- 비전공자sqld
- 항해15기
- java알고리즘문제풀이
- 프로그래머스
- sqld자격증합격
- java map 출력
- java set 출력
- 컴파일
- java참조자료형
- 격파르타비전공자
- 작은수제거하기
- java map
- 코딩부트캠프후기
- Today
- Total
코딩과 결혼합니다
230826 - 댓글 + 대댓글 좋아요 기능 구현 본문
✔️문제
댓글 테이블과 대댓글 테이블을 따로 만들게 되면서 로직이 굉장히 복잡하고 관리가 어려워졌다. 대댓글 작성, 수정, 삭제, 좋아요 까지는 만들었으나 post를 조회할 때 comment와 연관관계인 recomment까지 조회로 불러와서 사용자가 대댓글에 좋아요를 눌렀는지 안 눌렀는지를 나타내는 과정이 너무도 어려웠다.
✔️해결
프런트에서 post조회와 comment조회를 따로 만들어 달라던게 생각나서 따로 분리해 주었다. 조회를 따로 분리하니 댓글 조회할 때 대댓글에 대한 사용자의 좋아요 여부를 넣어주면 되어 좀 더 편해졌다.
✔️별도의 테이블로 관리하는 경우 장 · 단점
- 성능: 대규모 애플리케이션에서는 댓글과 대댓글을 별도의 테이블로 분리하여 쿼리 성능을 최적화할 수 있다. 댓글만 필요한 경우 대댓글 테이블을 조인하지 않아도 된다.
- 유지보수: 코드와 데이터베이스 스키마를 관리하기 쉽다. 댓글과 대댓글에 대한 변경이 각각의 테이블에 영향을 미치지 않는다.
- 단점: 두 개의 테이블을 유지해야 하므로 스키마가 조금 더 복잡할 수 있다.
Comment Controller
//comment 상세 조회
@GetMapping("/get/{postId}")
public CommentListResponse getOneComment(@PathVariable Long postId,
@AuthenticationPrincipal UserDetailsImpl userDetails,
int size,
int page) {
User user = userDetails != null ? userDetails.getUser() : null;
return commentService.getCommentByPostId(page-1, size, postId, user);
}
* 조회를 할 때 비회원과 회원을 구분해 준다. 회원정보가 존재하면 그 회원이 해당 댓글에 좋아요를 눌렀는지 누르지 않았는지 확인할 수 있다. (commentHasLiked/ ReCommentHasLiked) 프런트는 comment의 id를 알 수 없다고 하니 post Id를 통해서 comment를 가져온다.
Comment Service
//comment 조회
public CommentListResponse getCommentByPostId(int page, int size, Long postId, User user) {
// postId 유효성 확인
if (!postRepository.existsById(postId)) {
throw new IllegalArgumentException("해당 게시물이 존재하지 않습니다.");
}
Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
Page<Comment> commentPages = commentRepository.findAllByPostId(postId, pageable);
List<CommentResponseDto> commentResponseDtos = new ArrayList<>();
for (Comment comment : commentPages) {
List<ReCommentResponseDto> reComments = comment.getReCommentList().stream()
.map(reComment -> getOneReComment(reComment.getId(), user))
.collect(Collectors.toList());
boolean hasLikeComment = user != null && commentLikeRepository.existsLikeByCommentAndUser(comment, user);
commentResponseDtos.add(new CommentResponseDto(comment, hasLikeComment, reComments));
}
return new CommentListResponse(commentResponseDtos,commentPages.getTotalPages(), commentPages.getTotalElements(), size);
}
comment 부분이 길어질 수 있으니 페이징 처리를 해주었다.
다음 commentPages에 내가 불러오고 싶은 post에 달린 댓글들을 모두 가져와서 저장한다.
postId를 통해 찾은 post가 있는지 확인하고 없으면 에러처리, 다음으로 comment와 그리고 recomment 각각 사용자 정보가 있는지 없는지에 따라서 좋아요에 대한 여부를 확인하는 로직을 구현하였다.
Comment Entity
@Entity
@Getter
@Setter
@Table(name = "comments")
@NoArgsConstructor
public class Comment extends Auditing {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "comment_id")
private Long id;
@Column
private String nickname;
@Column(nullable = false, length = 500)
private String comment;
@JsonBackReference
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id")
private Post post;
@JsonManagedReference
@OneToMany(mappedBy = "comment", cascade = {CascadeType.REMOVE})
private List<ReComment> reCommentList = new ArrayList<>();
@JsonManagedReference
@OneToMany(mappedBy = "comment", cascade = {CascadeType.REMOVE})
private List<Commentlike> commentLike = new ArrayList<>();
private String userImg;
@Transient
private boolean commentHasLiked;
public Comment(CommentRequestDto requestDto, String nickname, Post post) {
this.nickname = nickname;
this.comment = requestDto.getComment();
this.post = post;
}
public void update(CommentRequestDto requestDto) {
this.comment = requestDto.getComment();
}
}
ReComment Entity
@Entity
@Getter
@Setter
@Table(name = "re_comments")
@NoArgsConstructor
public class ReComment extends Auditing {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "re_comment_id")
private Long id;
@Column
private String nickname;
@Column(nullable = false, length = 500)
private String reComment;
@JsonBackReference
@ManyToOne
@JoinColumn(name = "comment_id")
private Comment comment;
private String userImg;
@Transient
private boolean reCommentHasLiked;
@OneToMany(mappedBy = "reComment", cascade = {CascadeType.REMOVE})
private List<ReCommentLike> reCommentLikes = new ArrayList<>();
public ReComment(ReCommentRequestDto requestDto, String nickname, Comment comment) {
this.nickname = nickname;
this.reComment = requestDto.getReComment();
this.comment = comment;
}
public void update(ReCommentRequestDto requestDto) {
this.reComment = requestDto.getReComment();
}
}
결과
비회원일 때에는 HasLiked가 모두 false로, 회원일 때는 본인이 좋아요를 누른 post나 댓글에 true가 뜬다.
다음은 comment를 지웠을 때 연관된 것들도 지우며 걸리는 시간
잉 생각보다 얼마 안 걸리네?
'코딩과 매일매일♥ > Seoulvival' 카테고리의 다른 글
230829 - 알림기능 구현하기(알림 리스트) (0) | 2023.08.29 |
---|---|
230828 - 스크랩 기능 (0) | 2023.08.29 |
230824 - 인기 순위 태그 조회하기 (0) | 2023.08.25 |
230821 - 코드 리팩토링! 57줄이나 줄었어용 ^^ (2) | 2023.08.21 |
230818 - [ERD 설계]기획과 데이터를 다루는 것을 빡세게 생각 하고 정하는 것의 중요성 (0) | 2023.08.19 |