1. 요구 사항
댓글1
대댓글1
대댓글2
대댓글3
댓글2
대댓글1
댓글뿐만 아니라 댓글에 대댓글을 달 수 있는 계층형 구조로 구현하고 싶었다.
댓글을 삭제 한다면 대댓글까지 모두 삭제하여야 한다.
2. domain
@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@Builder
public class Comment extends BaseTimeEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // 기본키
@Column(columnDefinition = "TEXT", nullable = false)
private String comment; // 댓글 내용
@ManyToOne
private Member commentWriter; // 댓글 쓴 회원
@ManyToOne
private Post post; //댓글 단 게시물
@ManyToOne(fetch = FetchType.LAZY)
private Comment parentComment; //부모 댓글 (그냥 댓글)
@OneToMany(mappedBy = "parentComment", orphanRemoval = true)
private List<Comment> children = new ArrayList<>(); //자식 댓글(대댓글)
public void update(String comment){
this.comment = comment;
}
여기서 우리가 봐야 할 부분은
@ManyToOne(fetch = FetchType.LAZY)
private Comment parentComment;
@OneToMany(mappedBy = "parentComment", orphanRemoval = true)
private List<Comment> children = new ArrayList<>();
이 부분이다.
같은 domain class에 다대 일 관계를 만들어준다.
이렇게 한 댓글(parentComment)에 여러개의 대댓글(children)을 달 수 있게 매핑해준다.
- @ManyToOne(fetch = FetchType.Lazy)
: 부모 댓글이다. 즉, 그냥 댓글이다.
: fetch type을 lazy로 하여 필요한 시점에만 데이터를 불러 온다.
- @OneToMany(mappedBy = "parentComment", orphanRemoval = true)
: 자식 댓글이다. 즉, 대댓글이다.
: parentComment 을 매핑한다.
: orphanRemoval = true -> 부모 댓글을 삭제 하면 자식댓글까지 저절로 삭제 된다.
3. 댓글, 대댓글 생성
public Long saveComment(CommentDto commentDto, Long id, Member member) {
Post post = postRepository.findById(id).orElseThrow(); // 댓글 을 단 게시물
if (commentDto.getParentComment() != -1) { //부모 댓글이 존재 한다 = 자식 댓글 = 대댓글
Comment commentParent = commentRepository.findById(commentDto.getParentComment()).orElseThrow();
// CommentDto에서 가져온 부모 댓글 아이디로 부모 댓글을 가져 온다.
commentRepository.save(Comment.builder()
.comment(commentDto.getComment())
.commentWriter(member)
.post(post)
.parentComment(commentParent)
.build());
// 댓글내용, 댓글 쓴 회원, 게시물, 부모 댓글 을 저장한다.
} else { // 부모 댓글이 존재 하지 않는다 = 부모 댓글 = 댓글
commentRepository.save(Comment.builder()
.comment(commentDto.getComment())
.commentWriter(member)
.post(post)
.build());
// 댓글내용, 댓글 쓴 회원, 게시물을 저장한다.
}
return id;
}
- 프론트 쪽에서 현재 로그인한 회원, 게시물 번호, Comment Dto로 댓글 내용, 부모 댓글 기본키 id(parentComment)를 가지고 왔다.
- 저장 할때에는 부모 댓글이냐 자식댓글이냐에 따라 repository에 저장하는 방식이 다르다.
- parentComment == -1 즉 자신이 부모 댓글이면 parentComment 를 저장하지 않는다 -> null
- parentComment != -1 이면 부모댓글의 기본키 값이 존재 하기 때문이기 때문에 그 댓글의 대댓글이다. 이럴때는 repository에 parentComment 값을 저장 해준다.
4. DB Test
- 댓글, 대댓글 을 단 화면
- 댓글, 대댓글 DB
: 부모 댓글 일땐 parent_comment_id(댓글) 가 null 처리 되어 있고
: 자식 댓글 일땐 parent_comment_id(대댓글)가 부모 댓글 id로 저장되어 있다.
- 부모 댓글 테스트 1 삭제 후
: 부모 댓글1 테스트 뿐만 아니라 자식 댓글인 1-1, 1-2도 자동으로 삭제 되었다.
'Springboot' 카테고리의 다른 글
[SpringSecurity] 비밀번호 암호화 (BCryptPasswordEncoder) (0) | 2023.07.24 |
---|---|
[SpringSecurity] RememberMe (로그인 유지) (0) | 2023.02.21 |
[Sprong Boot]Swagger 사용하기 (0) | 2023.02.02 |
[Spring Boot]OAuth2 (NAVER, KAKAO, GOOGLE LOGIN) (0) | 2023.01.31 |
Annotation 생성하기 @CurrentMember (0) | 2023.01.31 |