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 19, 2023
1 parent 4a3fcd1 commit 1a96f29
Show file tree
Hide file tree
Showing 12 changed files with 181 additions and 39 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 @@ -72,15 +77,41 @@ public ResponseEntity<DataResponseDto<?>> getComment(@PathVariable("comment-id")
mapper.commentToCommentResponseDto(commentService.findComment(commentId));
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();
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<>();

List<CommentResponseDto> commentResponseDtos = mapper.commentsToCommentResponseDtos(comments);
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<>(commentResponseDtos, commentPage));
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 @@ -9,6 +9,7 @@
@Builder
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 @@ -19,8 +22,16 @@
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);
}

Expand All @@ -37,6 +48,11 @@ public Page<Comment> findComments(int page, int size) {
page, size, Sort.by("commentId").ascending()
));
}

@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 Down
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
12 changes: 6 additions & 6 deletions server/src/main/resources/application-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ spring:

jpa:
hibernate:
ddl-auto: none
ddl-auto: create
show-sql: true
properties:
hibernate:
Expand Down Expand Up @@ -72,11 +72,11 @@ server:
servlet:
encoding:
force-response: true
ssl:
key-store: classpath:keystore.p12
key-store-type: PKCS12
key-store-password: ${SSL_PASSWORD}
port: 8080
# ssl:
# key-store: classpath:keystore.p12
# key-store-type: PKCS12
# key-store-password: ${SSL_PASSWORD}
# port: 8080

mail:
address:
Expand Down
2 changes: 1 addition & 1 deletion server/src/main/resources/application.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
spring:
profiles:
active: server
active: local

0 comments on commit 1a96f29

Please sign in to comment.