1. 회원 정보 조회 DTO

DB에서 ID, 유저네임과 이메일을 가지고 온다.
package shop.mtcoding.blog.user;
import lombok.Data;
public class UserResponse {
// 엔티티를 dto로. 그래서 응답은 풀생성자가 필요함
@Data
public static class DTO{
private int id ;
private String username;
private String email;
public DTO(User user) {
this.id = user.getId();
this.username = user.getUsername();
this.email = user.getEmail();
}
}
}
만약 Lazy Loading 이 발생한다면 getter 가 호출될 때 발생한다.
public UserResponse.DTO 회원조회(int id){
User user = userJPARepository.findById(id)
.orElseThrow(() -> new Exception404("회원정보를 찾을 수 없습니다."));
return new UserResponse.DTO(user) ;//엔티티 생명 종료, 여기서 레이지 로딩 종료
}
@GetMapping("/api/users/{id}")
public ResponseEntity<?> userinfo(@PathVariable Integer id){
UserResponse.DTO responseDTO = userService.회원조회(id);
return ResponseEntity.ok(new ApiUtil(responseDTO));
}

2. 게시글 목록 조회 DTO

DB에서 ID, title 을 가지고 온다.
package shop.mtcoding.blog.board;
import lombok.Data;
import shop.mtcoding.blog.user.User;
public class BoardResponse {
@Data
public static class MainDTO{
private int id;
private String title;
public MainDTO(Board board) {
this.id = board.getId();
this.title = board.getTitle();
}
}
}
public List<BoardResponse.MainDTO> 글목록조회() {
Sort sort = Sort.by(Sort.Direction.DESC, "id");
List<Board> boardList = boardJPARepository.findAll(sort);
return boardList.stream().map(board -> new BoardResponse.MainDTO(board)).toList();
}
@GetMapping("/")
public ResponseEntity<?> main(){
List<BoardResponse.MainDTO> responseDTO = boardService.글목록조회();
return ResponseEntity.ok(new ApiUtil(responseDTO));
}

DTO 를 사용하면 원하는 데이터만 가지고 통신을 할 수 있다.
3. 상세보기 DTO
boardId, title content boarUserId username replyId comment replyUserId replyUsername
{
"id":1,
"title":"제목1",
"content":"내용1",
"user":{
"id":1,
"username":"ssar"
}
"re
}
DTO 에는 화면에 보이는 정보와 보이지 않더라도 ID를 함께 담아야 한다. 페이지의 권한 여부는 페이지에서 보이지 않기 때문에 ID가 있다면 프론트에서 권한 처리 할 수 있다.
@Data
public static class DetailDTO{
private int id;
private String title;
private String content ;
private int userId ;
private String usernaem; // 게시글 작성자
private boolean isOwner ;
private List<ReplyDTO> replies = new ArrayList<>(); // new 를해서 초기화해야 값이 없을 때 0의 빈 배열을 리턴함. null 이면 터짐
public DetailDTO(Board board, User sessionUser) {
this.id = board.getId();
this.title = board.getTitle();
this.content = board.getContent();
this.userId = board.getUser().getId();
this.usernaem = board.getUser().getUsername();
this.isOwner = false;
if(sessionUser!=null){
if(sessionUser.getId()==userId){
isOwner =true ;
}
}
//List 타입을 api 스트림으로 DTO 타입으로 담는다.
this.replies = board.getReplies().stream().map(reply -> new ReplyDTO(reply,sessionUser)).toList();
}
@Data
public class ReplyDTO{
private int id ;
private String content ;
private int userId ;
private String username ; // 댓글 작성자
private boolean isOwner ;
public ReplyDTO(Reply reply,User sessionUser) {
this.id = reply.getId();
this.content = reply.getComment();
this.userId = reply.getUser().getId();
this.username = reply.getUser().getUsername(); //lazy loading 발동
this.isOwner = false;
if(sessionUser!=null){
if(sessionUser.getId()==userId){
isOwner =true ;
}
}
}
}
public BoardResponse.DetailDTO 글상세보기(int boardId, User sessionUser) {
Board board = boardJPARepository.findByIdJoinUser(boardId)
.orElseThrow(() -> new Exception404("게시글을 찾을 수 없습니다"));
return new BoardResponse.DetailDTO(board,sessionUser);
}
@GetMapping("/api/boards/{id}/detail")
public ResponseEntity<?> detail(@PathVariable int id){
User sessionUser = (User) session.getAttribute("sessionUser");
BoardResponse.DetailDTO responseDTO = boardService.글상세보기(id,sessionUser);
return ResponseEntity.ok(new ApiUtil(responseDTO));
}


처음

4. 예외 경우
select * from board_tb ;
select count(id) from reply_tb where board_id = 4;
select id, title, content, user_id, (select count(id) from reply_tb where board_id = bt.id) reply_count from board_tb bt;

만약 이런 서브 쿼리로 댓글의 갯수를 포함한 데이터를 DTO로 받고 싶다면 ?
public class BoardResponse {
@AllArgsConstructor
@Data
public static class CountDTO {
private Integer id ;
private String title ;
private String content;
private Integer userId ;
private Long replyCount ;
}
}
@Query("select new shop.mtcoding.blog.board.BoardResponse$CountDTO(b.id, b.title, b.content, b.user.id, (select count(r.id) from Reply r where r.board.id = b.id)) from Board b")
List<BoardResponse.CountDTO> findAllWithReplyCount(); //<> 내부는 원래 Board 타입만 받을 수 잇음
// 클래스 내부에 static 으로 DTO를 만든다면 $ 를 사용해서 클래스$DTO 로 표시해야 한다.
@Test
public void findAllWithCount_test(){
List<BoardResponse.CountDTO> CountDTOList = boardJPARepository.findAllWithReplyCount();
for(int i=0;i<CountDTOList.size();i++){
System.out.println(CountDTOList.get(i));
}
}


Share article