Skip to content

Commit

Permalink
feat: 계층형댓글 create read 구현 #63
Browse files Browse the repository at this point in the history
  • Loading branch information
Sangyoo committed Feb 26, 2023
1 parent 1ab4c3b commit 912a5bc
Show file tree
Hide file tree
Showing 12 changed files with 282 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.main36.pikcha.domain.comment.controller;

import com.main36.pikcha.domain.comment.dto.CommentDetailResponseDto;
import com.main36.pikcha.domain.comment.dto.CommentDto;
import com.main36.pikcha.domain.comment.dto.CommentResponseDto;
import com.main36.pikcha.domain.comment.entity.Comment;
import com.main36.pikcha.domain.comment.mapper.CommentMapper;
import com.main36.pikcha.domain.comment.service.CommentService;
import com.main36.pikcha.domain.member.entity.Member;
import com.main36.pikcha.domain.post.entity.Post;
import com.main36.pikcha.domain.post.service.PostService;
import com.main36.pikcha.global.aop.LoginUser;
import com.main36.pikcha.global.response.DataResponseDto;
Expand All @@ -20,7 +22,10 @@

import javax.validation.Valid;
import javax.validation.constraints.Positive;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@Slf4j
Expand All @@ -44,9 +49,9 @@ public ResponseEntity<DataResponseDto<?>> postComment(Member loginUser,
commentBuilder
.commentContent(commentPostDto.getCommentContent())
.member(loginUser)
.post(postService.findPost(postId))
.post(postService.findPostNoneSetView(postId))
.build()
);
,commentPostDto.getParentId());

CommentResponseDto commentResponseDto = mapper.commentToCommentResponseDto(comment);

Expand All @@ -73,15 +78,40 @@ public ResponseEntity<DataResponseDto<?>> getComment(@PathVariable("comment-id")
return ResponseEntity.ok(new DataResponseDto<>(response));
}

@GetMapping()
public ResponseEntity<MultiResponseDto<?>> getComment(@Positive @RequestParam(required = false, defaultValue = "1") int page,
@GetMapping("/listof/{post-id}")
public ResponseEntity<MultiResponseDto<?>> getComment(@PathVariable("post-id") @Positive long postId,
@Positive @RequestParam(required = false, defaultValue = "1") int page,
@Positive @RequestParam(required = false, defaultValue = "10") int size) {
Page<Comment> commentPage = commentService.findComments(page - 1, size);
List<Comment> comments = commentPage.getContent();

List<CommentResponseDto> commentResponseDtos = mapper.commentsToCommentResponseDtos(comments);

return ResponseEntity.ok(new MultiResponseDto<>(commentResponseDtos, commentPage));
Post findPost = postService.findPostNoneSetView(postId);
Page<Comment> commentPage = commentService.findComments(page - 1, size, findPost);
List<Comment> commentList = commentPage.getContent();
for(Comment c : commentList) {
log.info(c.getCommentContent());
}
List<CommentDetailResponseDto> result = new ArrayList<>();
Map<Long, CommentDetailResponseDto> map = new HashMap<>();

commentList.stream().forEach(c-> {
CommentDetailResponseDto rDto = CommentDetailResponseDto.convertCommentToDto(c);
// map <댓글Id, responseDto>
map.put(c.getCommentId(), rDto);
// 댓글이 부모가 있다면
if(c.getParent() != null) {
// 부모 댓글의 id의 responseDto를 조회한다음
map.get(c.getParent().getCommentId())
// 부모 댓글 responseDto의 자식으로
.getChildren()
// rDto를 추가한다.
.add(rDto);
}
// 댓글이 최상위 댓글이라면
else{
// 그냥 result에 추가한다.
result.add(rDto);
}
});

return ResponseEntity.ok(new MultiResponseDto<>(result, commentPage));
}

@LoginUser
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.main36.pikcha.domain.comment.dto;

import com.main36.pikcha.domain.comment.entity.Comment;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

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

@Getter
@Setter
@Builder
public class CommentDetailResponseDto {
private Long commentId;
private Long parentId;
private Long memberId;
private String username;
private String memberPicture;
private String commentContent;
private LocalDateTime createdAt;
private LocalDateTime modifiedAt;
private List<CommentDetailResponseDto> children;

public static CommentDetailResponseDto convertCommentToDto(Comment comment){
return CommentDetailResponseDto.builder()
.commentId(comment.getCommentId())
.parentId(comment.getParent() == null ? null : comment.getParent().getCommentId())
.memberId(comment.getMember().getMemberId())
.username(comment.getMember().getUsername())
.memberPicture(comment.getMember().getPicture())
.commentContent(comment.getCommentContent())
.createdAt(comment.getCreatedAt())
.modifiedAt(comment.getModifiedAt())
.children(new ArrayList<>())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public class CommentDto {

@Getter
public static class Post {
private Long parentId;
@NotBlank(message = "댓글 내용을 입력해주세요.")
private String commentContent;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@Data
public class CommentResponseDto {
private Long commentId;
private Long parentId;
private Long memberId;
private String username;
private String memberPicture;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,17 @@ public class Comment extends Auditable {
private Post post;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "comment_id")
@JoinColumn(name = "parent")
private Comment parent;

@OneToMany(fetch = FetchType.LAZY, mappedBy = "parent")
public void updateParent(Comment parent){
this.parent = parent;
}

@OneToMany(fetch = FetchType.LAZY, mappedBy = "parent", orphanRemoval = true)
private List<Comment> children = new ArrayList<>();

public List<Comment> getChildren(){
return this.children;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.main36.pikcha.domain.comment.mapper;

import com.main36.pikcha.domain.comment.dto.CommentDetailResponseDto;
import com.main36.pikcha.domain.comment.dto.CommentDto;
import com.main36.pikcha.domain.comment.dto.CommentResponseDto;
import com.main36.pikcha.domain.comment.entity.Comment;
Expand All @@ -16,7 +17,15 @@ public interface CommentMapper {
@Mapping(target = "username", source = "member.username")
@Mapping(target = "memberId", source = "member.memberId")
@Mapping(target = "memberPicture", source = "member.picture")
@Mapping(target = "parentId", source = "parent.commentId")
CommentResponseDto commentToCommentResponseDto(Comment comment);

@Mapping(target = "username", source = "member.username")
@Mapping(target = "memberId", source = "member.memberId")
@Mapping(target = "memberPicture", source = "member.picture")
@Mapping(target = "parentId", source = "parent.commentId")
CommentDetailResponseDto commentToCommentDetailResponseDto(Comment comment);

List<CommentResponseDto> commentsToCommentResponseDtos(List<Comment> comments);
List<CommentDetailResponseDto> commentsToCommentDetailResponseDtos(List<Comment> comments);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,9 @@

import com.main36.pikcha.domain.comment.entity.Comment;
import com.main36.pikcha.domain.post.entity.Post;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.stereotype.Repository;
import java.util.List;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import static com.main36.pikcha.domain.comment.entity.QComment.comment;

@Repository
public class CommentCustomRepository {
private JPAQueryFactory jpaQueryFactory;

public CommentCustomRepository(JPAQueryFactory jpaQueryFactory) {
this.jpaQueryFactory = jpaQueryFactory;
}

public List<Comment> findCommentByPost(Post post){
return jpaQueryFactory.selectFrom(comment)
.leftJoin(comment.parent)
.fetchJoin()
.where(comment.post.postId.eq(post.getPostId()))
.orderBy(comment.parent.commentId.asc().nullsFirst(), comment.createdAt.asc())
.fetch();
}
public interface CommentCustomRepository {
Page<Comment> findCommentByPost(Post post, Pageable pageable);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.main36.pikcha.domain.comment.repository;

import com.main36.pikcha.domain.comment.entity.Comment;
import com.main36.pikcha.domain.post.entity.Post;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.support.PageableExecutionUtils;
import org.springframework.stereotype.Repository;

import java.util.List;

import static com.main36.pikcha.domain.comment.entity.QComment.comment;

@Repository
public class CommentCustomRepositoryImpl implements CommentCustomRepository{
private JPAQueryFactory jpaQueryFactory;

public CommentCustomRepositoryImpl(JPAQueryFactory jpaQueryFactory) {
this.jpaQueryFactory = jpaQueryFactory;
}

@Override
public Page<Comment> findCommentByPost(Post post, Pageable pageable) {
List<Comment> commentList = findCommnetList(post, pageable);

JPAQuery<Long> countQuery = getCount(post);

return PageableExecutionUtils.getPage(commentList, pageable, ()-> countQuery.fetchOne());
}

private JPAQuery<Long> getCount(Post post) {
JPAQuery<Long> countQuery = jpaQueryFactory
.select(comment.count())
.from(comment)
.where(comment.post.postId.eq(post.getPostId()));

return countQuery;
}

private List<Comment> findCommnetList(Post post, Pageable pageable){
return jpaQueryFactory.selectFrom(comment)
.leftJoin(comment.parent)
.fetchJoin()
.where(comment.post.postId.eq(post.getPostId()))
.orderBy(comment.parent.commentId.asc().nullsFirst(), comment.createdAt.asc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.main36.pikcha.domain.comment.service;

import com.main36.pikcha.domain.comment.dto.CommentDto;
import com.main36.pikcha.domain.comment.entity.Comment;
import com.main36.pikcha.domain.comment.repository.CommentCustomRepositoryImpl;
import com.main36.pikcha.domain.comment.repository.CommentRepository;
import com.main36.pikcha.domain.post.entity.Post;
import com.main36.pikcha.global.exception.BusinessLogicException;
import com.main36.pikcha.global.exception.ExceptionCode;
import lombok.RequiredArgsConstructor;
Expand All @@ -11,20 +14,28 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Service
@Transactional
@RequiredArgsConstructor
public class CommentService {

private final CommentRepository commentRepository;
private final CommentCustomRepositoryImpl customRepository;

public Comment createComment(Comment comment) {
public Comment createComment(Comment comment, Long parentId) {
// 부모가 있는 댓글이라면
if(parentId != null) {
// 부모댓글의 유효성 검증
Comment parent = findVerifiedComment(parentId);
// 부모 아래에 추가
comment.updateParent(parent);
}
return commentRepository.save(comment);
}

public Comment updateComment(Comment comment) {
return commentRepository.save(comment);
}
public Comment updateComment(Comment comment){ return commentRepository.save(comment);}

@Transactional(readOnly = true)
public Comment findComment(long commentId) {
Expand All @@ -38,6 +49,10 @@ public Page<Comment> findComments(int page, int size) {
));
}

@Transactional(readOnly = true)
public Page<Comment> findComments(int page, int size, Post post){
return customRepository.findCommentByPost(post, PageRequest.of(page, size));
}
public void deleteComment(Comment comment) {
commentRepository.delete(comment);
}
Expand All @@ -51,12 +66,13 @@ public Comment findVerifiedComment(long commentId) {
public Comment verifyClientId(long clientId, long commentId) {

Comment comment = findComment(commentId);
if (clientId == 1) return comment;
if(clientId == 1) return comment;
if (!(comment.getMember().getMemberId().equals(clientId))) {
throw new BusinessLogicException(ExceptionCode.USER_IS_NOT_EQUAL);
}

return comment;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ default PostResponseDto.Detail postToPostDetailResponseDto(Post post) {
.map(comment -> {
return CommentResponseDto.builder()
.commentId(comment.getCommentId())
.parentId(comment.getParent().getCommentId())
.memberId(comment.getMember().getMemberId())
.username(comment.getMember().getUsername())
.memberPicture(comment.getMember().getPicture())
Expand Down
Loading

0 comments on commit 912a5bc

Please sign in to comment.