본문 바로가기
Dev/SpringBoot

JPA 사용해서 무한 계층 댓글 구현해보기 - 02

by VIPeveloper 2022. 1. 20.
반응형

이전 포스팅

 

JPA 사용해서 무한 계층 댓글 구현해보기 (infinite depth) - 01

페이스북에서 보던 무한댓글(댓글의 댓글의 댓글의...) 은 어떻게 구현되는지 궁굼해서 이것저것 알아보다가 우연히 좋은 포스팅을 발견해서, 공부하고 응용해보는 작업을 해보려 한다. 1. 요구

dkyou.tistory.com

 

이전 포스팅에 이어 엔티티 개발을 시작해보자

 

3. 엔티티 개발

  • JPA를 까먹고 추가안했어서 추가해주었다.
import lombok.*;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;


@Entity
@Getter @Setter @EqualsAndHashCode(of = "id")
@Builder @NoArgsConstructor @AllArgsConstructor
public class Reply {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "reply_id")
    private Long id;

    private String content;

    private LocalDateTime createdDate;

    private LocalDateTime updatedDate;

    private Integer depth;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn (name ="parent_reply_id")
    private Reply parentReply;

    @OneToMany (mappedBy = "parentReply", cascade = CascadeType.ALL)
    private List<Reply> subReply = new ArrayList<>();
}

 

1. @ManyToOne (fetch = FetchType.LAZY)

  • JPA연관관계 적용 시 'xToOne' (ManyToOne, OneToOne)은 fetchType.EAGER를 기본 적용하고있다.
  • 지연 참조를 사용해줘야 n+1 문제 등 jpa 사용에 지장이 없다.
  • 가급적 fetch에는 LAZY를 적용시켜주어야 한다.

2. parentReply와 subReply

  • 셀프 조인을 위해 이 두 컬럼끼리 연관관계를 맺어준다.
  • mappedBy 속성을 통해 parentReply를 연관관계의 owner로 설정해준다.

4. Repository 개발

import org.springframework.data.jpa.repository.JpaRepository;

public interface ReplyRepository extends JpaRepository<Reply,Long> {
}
  • 아직 별다른 기능 추가가 없어서 기본형으로 만들어주었다.

5. DTO 개발

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Data
@Builder @NoArgsConstructor @AllArgsConstructor
public class ReplyDTO {

    private Long id;
    private String content;
    private LocalDateTime createdDate;
    private LocalDateTime updatedDate;
    private Integer depth;
    private ReplyDTO parentReply;
    private List<ReplyDTO> children = new ArrayList<>();

}
  • DTO를 구현하다보니 문득 이 프로젝트를 통해 진짜 궁굼했던 것에 다가가게 되었다.
  • Entity To Dto 시, Depth 가 무한일 경우 이건 stream으로 재귀 해결이 가능한지 궁굼했었다.
// Reply.java refactoring

public ReplyDTO toDto() {
    ReplyDTO build = ReplyDTO.builder()
            .id(this.id)
            .content(this.content)
            .createdDate(this.createdDate)
            .updatedDate(this.updatedDate)
            .depth(this.depth)
            .build();

    // 부모노드 설정
    Reply reply = this.getParentReply() == null ?
            new Reply() :
            this.getParentReply();
    build.setParentReply(reply.toDto());

    // 자식 노드 설정
    List<ReplyDTO> subReplyDTO = this.getSubReply() == null ?
            null :
            this.getSubReply().stream().map(Reply::toDto).collect(Collectors.toList());
    build.setChildren(subReplyDTO);

    return build;
}

 

얼른 테스트코드 짜보고싶다!

반응형