- [JPA] 26. 댓글 목록 보기 기능2024년 10월 17일
- Song hyun
- 작성자
- 2024.10.17.:53
728x90반응형[JPA] 26. 댓글 목록 보기 기능
1. BoardService 코드
/** * 게시글 상세보기 서비스, 게시글 주인 여부 판별 */ public Board getBoardDetails(int boardId, User sessionUser) { Board board = boardJPARepository .findById(boardId) .orElseThrow(() -> new Exception404("게시글을 찾을 수 없어요")); // 현재 사용자가 게시글을 작성했는지 여부 판별 boolean isBoardOwner = false; if(sessionUser != null ) { if(sessionUser.getId().equals(board.getUser().getId())) { isBoardOwner = true; } } // 집중 - 코드 추가 // 내가 작성한 댓글인가를 구현 해야 한다. board.getReplies().forEach( reply -> { boolean isReplayOwner = false; if(sessionUser != null) { if(sessionUser.getId().equals(reply.getUser().getId())) { isReplayOwner = true; } } // 객체에서만 존재하는 필드 - 리플 객체 엔티티 상태값 변경 처리 reply.setReplyOwner(isReplayOwner); }); board.setBoardOwner(isBoardOwner); return board; }
2. 지연 로딩 (Lazy Loading)
Hibernate: select b1_0.id, b1_0.content, b1_0.created_at, b1_0.title, b1_0.user_id from board_tb b1_0 where b1_0.id=? Hibernate: select r1_0.board_id, r1_0.id, r1_0.comment, r1_0.created_at, r1_0.status, r1_0.user_id from reply_tb r1_0 where r1_0.board_id=? Hibernate: select u1_0.id, u1_0.created_at, u1_0.email, u1_0.password, u1_0.role, u1_0.username from user_tb u1_0 where u1_0.id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
3. 즉시 로딩
Hibernate: select b1_0.id, b1_0.content, b1_0.created_at, b1_0.title, b1_0.user_id, r1_0.board_id, r1_0.id, r1_0.comment, r1_0.created_at, r1_0.status, r1_0.user_id from board_tb b1_0 left join reply_tb r1_0 on b1_0.id=r1_0.board_id where b1_0.id=? Hibernate: select u1_0.id, u1_0.created_at, u1_0.email, u1_0.password, u1_0.role, u1_0.username from user_tb u1_0 where u1_0.id in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
** 지연 로딩 - 쿼리 3번, 즉시 로딩 쿼리 2번, 즉 표면적으로는 Eager이 효율적으로 보일 수 있다. 하지만 카테시안 곱(Cartesian Product)과 데이터 중복 등 잠재적인 문제들이 발생할 수 있다!
**페치 전략(Fetch Strategy)를 어떻게 사용해야 할까?
1. 모든 연관관계에서는 기본적으로 지연 로딩을 사용한다. (특히 컬렉션일 때)
-하나의 엔티티가 다른 엔티티와 연결될 때, 필요한 시점까지 로딩을 지연하는 거싱 성능 면에서 유리하다.
-연관된 엔티티를 실제로 필요로 할 때만 로딩해 자원낭비를 줄일 수 있다.
2. 필요한 경우에만 연관된 엔티티를 함께 로딩한다.
-JPGL의 FETCH JOIN이나 네이티브 쿼리를 사용해, 연관된 엔티티를 한 번에 로딩한다.
-이를 통해 N+1 문제를 방지하고 성능을 최적화시킨다.
3. 페이징 처리 등으로 많은 데이터를 가져와야 할 때는 지연 로딩(LAZY) 전략에 배치 사이즈를 설정한다.
-배치 사이즈를 설정하면 지연 로딩 시, 한 번에 가져오는 엔티티 수를 조절할 수 있다.
-N+1 문제를 완화하고 DB 쿼리 횟수를 줄여 성능을 올릴 수 있다.
* application.yml 설정 체크!
결론 - 기본적으로 LAZY 전략 설정을 하고 많은 양에 데이터는 페이칭 처리를 한다.
spring: jpa: properties: hibernate: default_batch_fetch_size: 20
4. BoardRepository
// @Repository 생략 가능 public interface BoardJPARepository extends JpaRepository<Board, Integer> { // 커스텀 쿼리 메서드 만들어 보기 // Board 와 User 엔티티를 조인하여 특정 Board 엔티티를 조회 @Query("select b from Board b join fetch b.user u where b.id = :id") Optional<Board> findByIdJoinUser(@Param("id") int id); }
5. BoardService -게시글 상세보기 수정
** JPQL JOIN FETCH 사용, 즉 Board와 User 엔티티를 한 번에 조인 처리, 그리고 Reply는 Lazy 전략에 배치 사이즈 설정으로 가져오는 것
/** * 게시글 상세보기 서비스, 게시글 주인 여부 판별 */ public Board getBoardDetails(int boardId, User sessionUser) { // 전략 2번 // JPQL - JOIN FETCH 사용, 즉 User 엔티티를 한번에 조인 처리 Board board = boardJPARepository .findByIdJoinUser(boardId).orElseThrow(() -> new Exception404("게시글을 찾을 수 없습니다.")); // 전략을 1번 JAP 가 객체간에 관계를 통해 직접 쿼리를 만들고 가지고 왔다. // Board board = boardJPARepository // .findById(boardId) // .orElseThrow(() -> new Exception404("게시글을 찾을 수 없어요")); // 현재 사용자가 게시글을 작성했는지 여부 판별 boolean isBoardOwner = false; if(sessionUser != null ) { if(sessionUser.getId().equals(board.getUser().getId())) { isBoardOwner = true; } } // 집중 - 코드 추가 // 내가 작성한 댓글인가를 구현 해야 한다. board.getReplies().forEach( reply -> { boolean isReplayOwner = false; if(sessionUser != null) { if(sessionUser.getId().equals(reply.getUser().getId())) { isReplayOwner = true; } } // 객체에서만 존재하는 필드 - 리플 객체 엔티티 상태값 변경 처리 reply.setReplyOwner(isReplayOwner); }); board.setBoardOwner(isBoardOwner); return board; }
728x90반응형'JPA' 카테고리의 다른 글
[JPA] 28. 댓글 쓰기 및 삭제 및 인터셉터 적용 (2) 2024.10.17 [JPA] 27. 게시글 삭제 오류 해결하기 (0) 2024.10.17 [JPA] 25. 댓글 기능 작성하기 (1) 2024.10.16 [JPA] 24. Mustache를 사용한 Blog 제작 - 인터셉터 만들기 (0) 2024.10.11 [JPA] 23. Mustache를 사용한 Blog 제작 - 에러 컨트롤러 및 커스텀 익셉션 만들기 (0) 2024.10.11 다음글이전글이전 글이 없습니다.댓글