// 2. 게시글 전체 조회
// 전체 조회 : 제목,작성자명, 작성 내용, 작성 날짜
// 작성 날짜 기준, 내림차순 정렬
public List<PostCommentResponseDto> getPosts() {
List<Post> posts = postRepository.findAllByOrderByModifiedAtDesc();
List<PostCommentResponseDto> postCommentResponseDtos = new ArrayList<>();
for (Post post : posts) {
List<Comment> comments = commentRepository.findAllByPostidOrderByCreatedAtDesc(post.getId());
List<CommentResponseDto> commentResponseDtos = new ArrayList<>();
for (Comment comment : comments) {
commentResponseDtos.add(new CommentResponseDto(comment));
}
PostCommentResponseDto postCommentResponseDto = new PostCommentResponseDto(post, commentResponseDtos);
postCommentResponseDtos.add(postCommentResponseDto);
}
return postCommentResponseDtos;
}
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
List<Post> findAllByOrderByModifiedAtDesc();
Post findPostById(Long id);
}
💻 해결방안
for문 내에서 쿼리를 계속해서 호출해서
n+1의 문제가 발생
런타임 할 때, hibernate가
- List posts = postRepository.findAllByOrderByModifiedAtDesc();
- List comments = commentRepository.findAllByPostidOrderByCreatedAtDesc(post.getId());
- (post.getId())
세 번 호출이 되는데, 게시글의 수가 많을 수록 쿼리문의 호출수도 많아진다. 그래서 한 번 호출할 때 전체가 보이도록 수정해야 한다.
for (Post post : posts) {
// comments are already fetched with the post due to @EntityGraph
List<Comment> comments = post.getComments();
List<CommentResponseDto> commentResponseDtos = new ArrayList<>();
for (Comment comment : comments) {
commentResponseDtos.add(new CommentResponseDto(comment));
}
PostCommentResponseDto postCommentResponseDto = new PostCommentResponseDto(post, commentResponseDtos);
postCommentResponseDtos.add(postCommentResponseDto);
}
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
@EntityGraph(attributePaths = "comments")
List<Post> findAllByOrderByModifiedAtDesc();
Post findPostById(Long id);
}
@EntityGraph를 활용해 쿼리가 한 번 돌아가도록 수정
cascadeorphanRemoval의 차이
둘다 부모 자식의 entity 관계를 맺어주는 역할