개발 기록/도서관 관리 시스템

[Library Management System] 25.09.17 (48일)

dev.jelee 2025. 9. 17. 23:08

[ 작업한 내용 ]

< 사용자: 책 리뷰 전체 목록 조회(본인것) >

1. messages.properties

- 사용자(본인): 책 리뷰 전체 목록 관련 메시지 정의

success.review.list_fetched=리뷰 목록이 성공적으로 조회되었습니다.
error.review.not_found=리뷰를 찾을 수 없습니다.

2. ReviewSuccessCode

- 사용자(본인): 책 리뷰 전체 목록 성공 코드

REVIEW_LIST_FETCHED(HttpStatus.OK, "REVIEW_201", "success.review.list_fetched");

3. ReviewErrorCode

- 사용자(본인): 책 리뷰 전체 목록 에러 코드

REVIEW_NOT_FOUND(HttpStatus.NOT_FOUND, "REVIEW_404", "error.review.not_found");

3. UserReviewListResDTO

- 사용자(본인): 책 리뷰 전체 목록 응답 DTO.

- 책 제목, 리뷰 내용, 작성일, 수정일 (bookTitle, content, createdDate, updatedDate)

- Review 엔티티를 파라미터로 받는 생성자 함수 정의

@Getter
public class UserReviewListResDTO {
  private String bookTitle;
  private String content;
  private LocalDateTime createdDate;
  private LocalDateTime updatedDate;

  public UserReviewListResDTO(Review review) {
    this.bookTitle = review.getBook().getTitle();
    this.content = review.getContent();
    this.createdDate = review.getCreatedDate();
    this.updatedDate = review.getUpdatedDate();
  }
}

4. UserReviewController

- GET /api/v1/user/me/reviews 로 요청을 받는다.

- 요청 파라미터는 page, size이며 각 기본값은 0과 10이다.

- @AuthenticationPrincipal 주입으로 가져온 사용자 정보는 User 엔티티로 받아온다.

- Service 계층으로 page, size, user.getId()를 전달한다.

- 서비스로직으로 전달받은 결과와 성공메시지를 ApiResponse.success()로 감싸서 클라이언트 측으로 반환한다.

@GetMapping("/me/reviews")
public ResponseEntity<?> allListReview(
  @RequestParam(name = "page", defaultValue = "0") int page,
  @RequestParam(name = "size", defaultValue = "10") int size,
  @AuthenticationPrincipal User user) {
  
  // 서비스로직
  Page<UserReviewListResDTO> responseDTO = userReviewService.allListReview(page, size, user.getId());

  // 성공메시지
  String message = messageProvider.getMessage(ReviewSuccessCode.REVIEW_LIST_FETCHED.getMessage());
  
  return ResponseEntity
            .status(ReviewSuccessCode.REVIEW_LIST_FETCHED.getHttpStatus())
            .body(ApiResponse.success(
              ReviewSuccessCode.REVIEW_LIST_FETCHED, 
              message, 
              responseDTO));
}

5. UserReviewService

- userRepository.findById(userId)를 통해 사용자 존재 여부를 확인하고, 존재하지 않으면 UserErrorCode.USER_NOT_FOUND 예외를 발생시킨다.

- PageRequest.of(page, size)를 사용하여 Pageable 객체를 생성하고 페이징 정보를 정의한다.

- reviewRepository.findByUser_Id(user.getId(), pageable)로 사용자가 작성한 리뷰 목록을 페이지 단위로 조회한다.

- 조회된 Page<Review>를 List<UserReviewListResDTO>로 매핑한 뒤, 이를 PageImpl로 감싸 최종적으로  페이징 정보를 포함한 DTO 형태로 반환한다.

public Page<UserReviewListResDTO> allListReview(int page, int size, Long userId) {

  // 사용자 조회, 유효성 검사
  User user = userRepository.findById(userId)
      .orElseThrow(() -> new BaseException(UserErrorCode.USER_NOT_FOUND));

  // 페이징 정의
  Pageable pageable = PageRequest.of(page, size);

  // userId로 책 리뷰 조회
  Page<Review> result = reviewRepository.findByUser_Id(user.getId(), pageable);

  // Page DTO를 List DTO로 형변환.
  List<UserReviewListResDTO> listDTO = result.getContent()
      .stream()
      .map(UserReviewListResDTO::new)
      .toList();

  // List DTO를 PageImpl로 감싸서 페이징 형태로 반환.
  return new PageImpl<>(listDTO, result.getPageable(), result.getTotalElements());
}

6. ReviewRepository

- 사용자가 작성한 모든 책 리뷰를 userId로 조회하여 pageable로 정의한 메서드 정의.

Page<Review> findByUser_Id(Long userId, Pageable pageable);

commit
리뷰 목록 조회 내용 있는 경우(좌), 내용 없는 경우(우)