본문 바로가기

프로젝트/✍️ [전공자들]

[전공자들 12] 댓글/답글 기능 만들기 (spring/mongodb 내장객체)

일단, 화면설계를 조금 수정했다. 

기존 화면설계

 

바꾼 답글UI

 

원래 @태그를 사용해보고 싶었는데, NoSql로 어떻게 db에 넣어야 할 지, 그리고 @이름을 어떻게 인식해서 댓글/답글로 구분해야할 지 고민하다가 결국 없애버렸다. 

그래서 그냥 연한 회색처리로 댓글/답글을 구분하기로 했음. 

 

article구조

//Article
@Getter
@Setter
@ToString 
@NoArgsConstructor
@Document(collection = "article")
public class Article {
    @Id
    private String id;
    private String title;
    private String content;
    private MemberProfileDto writer;
    private String boardType;
    private String subject;
    private String middleMajor;
    private List<String> goods;
    private List<String> bads;
    private List<String> scraps;
    private List<CommentDto> comments; // 댓글
    @CreatedDate // 등록일 자동설정
    private Date createdAt;
    @LastModifiedDate // 수정일 자동설정
    private Date modifiedAt;

}

 

//Comment(댓글)
@Getter
@Setter
@ToString
public class CommentDto {
    @Getter
    private static int num=1;
    private int id;
    private MemberProfileDto from;
    @Transient
    private String to; //게시글id
    private String content;
    private String createdAt;
    private List<ReplyDto> replies;
    private List<String> sympathy;

    public static void numbering(){
        ++num;
    }
}

 

//Reply(답글)
@Getter
@Setter
@ToString
@NoArgsConstructor
public class ReplyDto {
    @Getter
    private static int num=1;
    private int id;
    private MemberProfileDto from;
    @Transient //db에는 들어가지 않게 하는 어노테이션
    private String articleId; //게시글id
    @Transient
    private int CommentId; //댓글id
    private String content;
    private String createdAt;
    private List<String> sympathy;
    public static void numbering(){
        num++;
    }
}

 

댓글과 답글이 가진 속성은 거의 비슷해서 사실 상속관계로 만들 수 있지 않을까 생각해봤는데 

댓글은 답글을 가지고 있고, 또 답글은 댓글 id를 가지고 있기 때문에 뭔가 관계가 복잡해지는 것 같아서 일단 각각 따로 만들었다. 기능을 완성시키고, 나중에 간결하게 만들 수 있는 방법을 공부해야겠다..

 

그리고 article은 collection으로 관리하기 때문에 @Id 어노테이션을 붙이면 몽고db에서 자동으로 고유한 id값을 설정해주는데 댓글과 답글은 article에 내장객체로만 넣어서 구별할 수 있는 값을 직접 설정해줘야 했다.

 

static 변수를 선언, 댓글 및 답글을 생성하는 service에서 numbering()호출을 통해 댓글을 작성할 때 마다 값을 증가시키고 id값으로 부여해줬다.

 

댓글생성 service

//Service
 @Override
    public Article createComment(CommentDto commentDto) throws Exception {
        commentDto.setReplies(new ArrayList<ReplyDto>()); 

        Member member = memberService.getCurrentMember();
        MemberProfileDto memberProfileDto = new MemberProfileDto(member);
        commentDto.setFrom(memberProfileDto); //작성자 기록
        //등록일 설정
        SimpleDateFormat format =  new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String strDate = format.format(new Date());
        commentDto.setCreatedAt(strDate);
        //공감
        commentDto.setSympathy(new ArrayList<String>());
        //댓글id직접설정
        commentDto.setId(CommentDto.getNum());
        CommentDto.numbering();

        //article update
        Article article = getArticleDetail(commentDto.getTo());
        List<CommentDto> comment = article.getComments();
        comment.add(commentDto);
        article.setComments(comment);

        return articleRepository.save(article);
    }

 

답글생성 service

@Override
    public Article createReply(ReplyDto replyDto) throws Exception {
        //등록일
        SimpleDateFormat format =  new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String strDate = format.format(new Date());
        replyDto.setCreatedAt(strDate);
        //공감수초기화
        replyDto.setSympathy(new ArrayList<String>());
        //답글작성자
        Member member = memberService.getCurrentMember();
        MemberProfileDto memberProfileDto = new MemberProfileDto(member);
        replyDto.setFrom(memberProfileDto);
        //id넘버링
        replyDto.setId(ReplyDto.getNum());
        ReplyDto.numbering();
        
        //article update 
        Article article = getArticleDetail(replyDto.getArticleId());
        for(CommentDto c : article.getComments()){
            if(c.getId()==replyDto.getCommentId()){
                List<ReplyDto> list = c.getReplies();
                list.add(replyDto);
                c.setReplies(list);
                break;
            }
        } 
        return articleRepository.save(article);
    }

 

@Id와 마찬가지로 document는 @CreatedDate를 통해서 생성일을 자동으로 설정할 수 있지만, 댓글과 답글 클래스들은 등록일을 직접 설정해줘야 했다. 

 

그리고 프론트에서 답글을 토글형식으로 숨겼다가 보일 수 있도록 만들었다. 

결과물

댓글 없을 때
댓글 유, 텍스트 있을 때 작성버튼 활성화
답글 및 공감 화면