Home > Today I Learned > 2026_05_04~2026_05_08 > 2026-05-06 일지

2026-05-06 일지
web spring thymeleaf html

대댓글 구현


서론

댓글 구현은 성공했고 이후 선택사항인 대댓글 구현에 관해 정리할 것이다.
프로젝트 동안 구현하느라 제대로 구현하지 못한 것을 정리 해볼 예정이다.
이번 프로젝트에서는 DB를 사용하지 않고 InMemory 구조로 저장을 했기 때문에
DB가 구현되지 않았다.

차이

트리 구조를 구현해야 하기 때문에 parentId가 필요하고 이후 대댓글의 깊이를 표현하기 위해 depth 값을 주어 관리하도록 했다.


    // 특정 게시물에 달린 댓글 목록을 조회하는 메서드
    public List<Comment> getCommentsByPost(int postId) {
        Post post = memoryRepository.findPostById(postId)
                .orElseThrow(() -> new IllegalArgumentException("게시글 없음"));

        List<Comment> result = new ArrayList<>();

        List<Comment> rootComments = post.getCommentMap()
                .values()
                .stream()
                .filter(comment -> comment.getParentId() == ROOT_PARENT_ID)
                .sorted(Comparator.comparing(Comment::getCreatedAt))
                .toList();

        //컨트롤러를 통해 post를 리디이렉트 시 comment를 구조에 맞게 삽입하는 기능 수행
        for (Comment root : rootComments) {

            result.add(root);

            addChildren(
                    root.getId(),
                    post.getCommentMap().values(),
                    result
            );
        }

        return result;
    }
 // 특정 댓글에 대댓글을 추가하는 메서드
    public void addReply(int postId, int parentId, String content) {
        Post post = memoryRepository.findPostById(postId)
                .orElseThrow(() -> new IllegalArgumentException("게시글 없음"));

        Comment parent = post.getCommentMap().get(parentId);

        if (parent == null) {
            throw new IllegalArgumentException("부모 댓글 없음");
        }

        int depth = parent.getDepth() + 1;

        addCommentInternal(postId, content, parentId, depth);

    }
// 댓글과 대댓글을 실제로 생성하고 저장하는 내부 공통 메서드
    private void addCommentInternal(
            int postId,
            String content,
            int parentId,
            int depth
    ) {
        Post post = memoryRepository.findPostById(postId)
                .orElseThrow(() -> new IllegalArgumentException("게시글 없음"));

        int commentId = memoryRepository.nextCommentId();

        if (commentId == parentId) {
            throw new IllegalStateException("댓글 id와 parentId가 같습니다.");
        }

        LocalDateTime now = LocalDateTime.now();

        Comment comment = new Comment(
                commentId,
                content,
                now,
                now,
                parentId,
                depth,
                new LinkedHashMap<>()
        );

        comment.setPost(post);

        post.getCommentMap().put(commentId, comment);
        MemoryRepository.comments.add(comment);
    }

댓글과 대댓글을 생성할때 사용하는 공통메서드는 중복요소가 있기 때문에 따로 빼서 만들어주었다.