본문 바로가기
Projects/청하-청년을 위한 커뮤니티 서비스

[청하] 16. 게시글 리스트 조회 기능 - 댓글수 반환 추가

by Lpromotion 2024. 10. 14.

댓글 기능에 추가됨에 따라 게시글 리스트 조회 시 댓글 수를 같이 반환하도록 수정하게 되었다. 댓글 수는 DB에 저장하고, 댓글 생성 API 요청이 있을 때 댓글 수가 증가되도록 했다.

 

1. 프로젝트 구조

src/main/java/com/example/withpeace/
│
├── domain/                 # 도메인 모델 (엔티티)
│   ├── Post.java           # 게시글 엔티티
│   └── Comment.java        # 댓글 엔티티
│
├── repository/                   # 데이터 접근 계층
│   ├── CommentRepository.java    # 댓글 레포지토리
│   └── PostRepository.java       # 게시글 레포지토리
│
├── dto/                              # 데이터 전송 객체
│   └── response/
│       └── PostListResponseDto.java  # 게시글 리스트 조회 응답 DTO
│
├── controller/             # 컨트롤러 계층
│   └── PostController.java # 게시글 관련 API 엔드포인트
│
└── service/                # 비즈니스 로직 계층
    └── PostService.java    # 게시글 관련 비즈니스 로직

 

2. 도메인 엔티티 구현

Post

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@DynamicUpdate
@Table(name = "posts")
public class Post {
    // ... (필드 생략)

    @Column(name = "comment_count", nullable = false)
    private Long commentCount;

    // ... (필드 생략)

    @Builder
    public Post(User writer, String title, String content, ETopic type) {
        this.writer = writer;
        this.title = title;
        this.content = content;
        this.type = type;
        this.commentCount = 0L; // 게시글 생성 시 댓글수 초기화
        this.createDate = LocalDateTime.now();
    }

    // ... (메서드 생략)

    public void increaseCommentCount() { this.commentCount++; } // 댓글수 증가 메서드
    public void decreaseCommentCount() { this.commentCount--; } // 댓글수 감소 메서드

}

`commentCount` 필드를 추가하고, 댓글수를 증가 또는 감소시킬 수 있는 `increaseCommentCount()`와 `decreaseCommentCount()` 메서드를 추가했다.

 

3. DTO 구현

PostListResponseDto

@Builder
public record PostListResponseDto(
        Long postId,
        String title,
        String content,
        ETopic type,
        Long commentCount, // 댓글수 필드 추가
        String createDate,
        String postImageUrl) {

    public static PostListResponseDto from(Post post, String postImageUrl) {
        return new PostListResponseDto(
                post.getId(),
                post.getTitle(),
                post.getContent(),
                post.getType(),
                post.getCommentCount(), // 댓글수 포함
                TimeFormatter.timeFormat(post.getCreateDate()),
                postImageUrl
        );
    }
}

게시글 리스트 조회 응답 DTO로 `commentCount` 필드를 추가하여 각 게시글의 댓글수를 조회할 수 있도록 했다.

 

4. 서비스 구현

댓글 등록 서비스 로직 수정

기존 코드

@Transactional
public Boolean registerComment(Long userId, Long postId, String content) {
    User user = getUserById(userId);
    Post post = getPostById(postId);

    commentRepository.save(Comment.builder()
            .post(post)
            .writer(user)
            .content(content)
            .build());
            
    return true;
}

 

수정 코드

@Transactional
public Boolean registerComment(Long userId, Long postId, String content) {
    User user = getUserById(userId);
    Post post = getPostById(postId);
    
    try {
	      // 댓글 저장
        commentRepository.save(Comment.builder()
                .post(post)
                .writer(user)
                .content(content)
                .build());
        // 게시글의 댓글수 증가
        post.increaseCommentCount();

        return true;
    } catch (Exception e) {
        throw new CommonException(ErrorCode.POST_ERROR);
    }

}

`commentRepository.save()` 로 댓글을 저장한 후 `post.increaseCommentCount()` 를 호출해 게시글의 댓글수를 증가시킨다.

 

5. API 응답 예시

요청 URL

[GET] http://cheongha.site/api/v1/posts?type=FREEDOM&pageIndex=0&pageSize=10

 

 

Response Body

{
  "data": [
    {
      "postId": 8,
      "title": "가을이 온 것 같네요!",
      "content": "선선한 날씨가 너무 좋네요!\\n시원해진 날씨에 다들 하고싶은게 있으신가요?!",
      "type": "FREEDOM",
      "commentCount": 0,
      "createDate": "2024/09/22 17:37:07",
      "postImageUrl": null
    },
    {
      "postId": 1,
      "title": "너무 덥네요ㅠ",
      "content": "ㅠㅠ",
      "type": "FREEDOM",
      "commentCount": 1,
      "createDate": "2024/07/17 22:23:58",
      "postImageUrl": "<https://storage.googleapis.com/cheong-ha-bucket/postImage/1/0_imageFile2488896157096969460.jpg>"
    }
  ],
  "error": null
}
반응형

댓글