게시글도 조회수 기능을 추가하게 되었다.
게시글 조회수는 이전 정책 조회수와 다르게, 시글 테이블에 조회수 컬럼을 직접 추가하여 더 간단하게 구현했다.
1. 프로젝트 구조
src/main/java/com/example/withpeace/
│
├── domain/ # 도메인 모델 (엔티티)
│ └── Post.java # 게시글 엔티티
│
├── repository/ # 데이터 접근 계층
│ └── PostRepository.java # 게시글 레포지토리
│
├── controller/ # 컨트롤러 계층
│ └── PostController.java # 게시글 관련 API 엔드포인트
│
└── service/ # 비즈니스 로직 계층
└── PostService.java # 게시글 관련 비즈니스 로직
2. 도메인 엔티티 수정
Post
public class Post {
// ... (기존 컬럼 생략)
// 조회수 컬럼 추가
@Column(name = "view_count", nullable = false)
private Long viewCount;
@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.viewCount= 0L; // 추가
this.createDate = LocalDateTime.now();
}
// ... (기존 메서드 생략)
// 조회수 증가
public void incrementViewCount() { this.viewCount++; }
}
Post 엔티티에 `viewCount`(조회수) 컬럼를 추가하고, 조회수를 증가시키는 `incrementViewCount` 메서드를 추가했다.
3. 서비스 코드 수정
PostService
@Transactional
public PostDetailResponseDto getPostDetail(Long userId, Long postId) {
getUserById(userId);
Post post = getPostById(postId);
List<String> postImageUrls = Optional.ofNullable(imageRepository.findUrlsByPost(post))
.orElse(Collections.emptyList());
List<CommentListResponseDto> comments = Optional.ofNullable(commentRepository.findCommentsByPost(post))
.orElse(Collections.emptyList())
.stream()
.map(comment -> CommentListResponseDto.builder()
.commentId(comment.getId())
.userId(comment.getWriter().getId())
.nickname(comment.getWriter().getNickname())
.profileImageUrl(comment.getWriter().getProfileImage())
.content(comment.getContent())
.createDate(TimeFormatter.timeFormat(comment.getCreateDate()))
.build())
.collect(Collectors.toList());
PostDetailResponseDto postDetailResponseDto =
PostDetailResponseDto.builder()
.postId(postId)
.userId(post.getWriter().getId())
.nickname(post.getWriter().getNickname())
.profileImageUrl(post.getWriter().getProfileImage())
.title(post.getTitle())
.content(post.getContent())
.type(post.getType())
.createDate(TimeFormatter.timeFormat(post.getCreateDate()))
.postImageUrls(postImageUrls)
.comments(comments)
.build();
post.incrementViewCount(); // 조회수 증가
return postDetailResponseDto;
}
`getPostDetail`는 “게시글 상세 조회”의 서비스 코드이다. 사용자가 한 게시글을 “상세 조회”하게 되면, 게시글의 상세 정보를 조회하고 마지막에 `incrementViewCount` 메서드를 호출하여 조회수를 증가시킨다.
게시글 조회수 증가 구현 로직 선택
“정책 조회수 기능 구현”에서는 조회수 컬럼을 추가할 수 없는 상황이어서 조회수 테이블을 따로 생성했고, 레포지토리를 이용하여 중복 방지를 할 수 있었다. 하지만 게시글은 Post 엔티티에 `viewCount` 컬럼을 추가하고, `incrementViewCount` 메서드를 사용하도록 했다.
그 이유로는
- 별도의 조회수 테이블을 생성하게 되면 추가적인 리소스가 더 필요하고 구조가 복잡해진다.
- 중복 방지도 중요하지만 단순한 조회수 카운팅을 우선순위로 생각했다.
- 추후 중복 방지가 필요해지면 그때 테이블을 분리하는 것이 더 효율적이라고 판단했다.
위 이유 이 외에도 Post 엔티티가 자신의 조회수를 직접 관리하는 것이 객체지향적 설계에 더 부합하고, *JPA의 기능(변경 감지) 을 통해 별도의 UPDATE 쿼리를 작성할 필요없이 자동으로 데이터베이스에 반영된다는 장점도 있다.
* JPA의 변경 감지(Dirty Checking) 기능: 엔티티의 변경사항을 감지하여 트랜잭션이 끝나는 시점에 데이터베이스에 자동으로 반영하는 기능
4. API 응답 예시
요청 URL
[GET] http://cheongha.site/api/v1/posts/10
“게시글 상세 조회” 시 조회수를 증가시킬 수 있다.
'Projects > 청하-청년을 위한 커뮤니티 서비스' 카테고리의 다른 글
[청하] 38. Docker 환경에서 Spring Boot 모니터링 시스템 구축 (with. Prometheus, Grafana) (2) | 2024.10.27 |
---|---|
[청하] 37. 로컬 환경에서 Spring Boot 모니터링 시스템 구축 (with. Prometheus, Grafana) (0) | 2024.10.27 |
[청하] 35. 정책 조회수 기능 구현 (1) | 2024.10.23 |
[청하] 34. 정책 찜하기 기능 - 유니크 제약조건 문제 해결 (0) | 2024.10.23 |
[청하] 33. 정책 조회 API - 찜하기 여부 추가 & 인증 설정 변경 (2) | 2024.10.23 |
댓글