28.인라인쿼리와 join

강재영's avatar
Sep 05, 2024
28.인라인쿼리와 join
 

인라인쿼리

notion image
 
 
notion image
실행순서가 from where select순 from으로 하드디크의 내용을 끌어올리고 실행하는데 select에 설정한 별칭은 where이 모르기에 실행이 안되다
-그러므로 인라인쿼리를 사용해서 먼저 등록시키면 where에 별칭을 사용할 수 있다.
 
 
notion image
뒤에 조인을 위해서 t1이라는 별칭을 만들었고 이걸 다시 join을 해서 뒤에 붙였다.
 
notion image
 
notion image
notion image
notion image
우리가 필요한 것들 중 중복되는 거를 제외한 내용들이다.(빨간박스부분만 필요함)
 

id가 중복되어 다시 짠 쿼리문

notion image
 

jpaRepository

@Query("select b from Board b join fetch b.user left join fetch b.replies r left join fetch r.user where b.id=:id") Optional<Board> mFindByWithReply(@Param("id")int id);
 
join fetch를 사용하면 lazy전략을 무시하고 다가져온다
 

log를 보면 다 가지오는걸 볼 수있다.

Hibernate: select b1_0.id, b1_0.content, b1_0.created_at, r1_0.board_id, r1_0.id, r1_0.comment, r1_0.created_at, u2_0.id, u2_0.created_at, u2_0.email, u2_0.password, u2_0.username, b1_0.title, u1_0.id, u1_0.created_at, u1_0.email, u1_0.password, u1_0.username from board_tb b1_0 join user_tb u1_0 on u1_0.id=b1_0.user_id left join reply_tb r1_0 on b1_0.id=r1_0.board_id left join user_tb u2_0 on u2_0.id=r1_0.user_id where b1_0.id=?
 
💡
또한 프론트에게 보낼때는 꼭 필요한 데이터필드만 보내야한다
public BoardResponse.DetailDTO 게시글상세보기(User sessionUser, Integer boardId){ Board boardPS = boardRepository.mFindByWithReply(boardId) .orElseThrow(() -> new Exception404("게시글이 없습니다.")); return new BoardResponse.DetailDTO(boardPS, sessionUser); }
 

BoardResponse.DetailDTO

 
package org.example.springv3.board; import lombok.Data; import org.example.springv3.reply.Reply; import org.example.springv3.user.User; import java.util.ArrayList; import java.util.List; public class BoardResponse { @Data public static class DetailDTO { private Integer id; private String title; private String content; private Boolean isOwner; private String username; //댓글듯 private List<ReplyDTO> replies = new ArrayList<>(); public DetailDTO(Board board, User sessionUser) { this.id = board.getId(); this.title = board.getTitle(); this.content = board.getContent(); this.isOwner = false; if (sessionUser != null) { if (board.getUser().getId() == sessionUser.getId()) { isOwner = true; // 권한체크 } } this.username = board.getUser().getUsername(); for(Reply reply : board.getReplies()){ replies.add(new ReplyDTO(reply, sessionUser)); } } @Data class ReplyDTO{ private Integer id; private String comment; private String username; private Boolean isOwner; public ReplyDTO(Reply reply, User sessionUser) { this.id = reply.getId(); this.comment = reply.getComment(); this.username = reply.getUser().getUsername(); this.isOwner = false; if (sessionUser != null) { if (reply.getUser().getId() == sessionUser.getId()) { isOwner = true; // 권한체크 } } } } } }
 

결과

notion image
플랫하게 나오는게 아니라 필요한데이터만 잘 정리해서 나왔다.
 

추가

 
openinvew false lazy 전략
안줌 그러니까 템플릿에서 호출하면 에러나옴
openinvew true lazy 전략 controller에서 템플릿으로 바꿔서 줄떄 get요청해서 가지고 감 문제가 생김
제일 좋은거는 서비스단에서 controller로 보낼 때 dto를 보내는게 베스트
 
Share article

강재영 블로그