[ 작업한 내용 ]
< 공용: 도서 전체 목록 조회 >
# UserBookListResDTO
- 도서 전체 목록 조회 응답 DTO
- 도서 고유번호, 제목, 저자, 출판사, 출판일, 상태, 위치 (id, title, author, publisher, publishedDate, status, location)
** 변경사항 없음
@Getter
public class UserBookListResDTO {
private Long id;
private String title;
private String author;
private String publisher;
private LocalDate publishedDate;
private BookStatus status;
private String location;
public UserBookListResDTO(Book book) {
this.id = book.getId();
this.title = book.getTitle();
this.author = book.getAuthor();
this.publisher = book.getPublisher();
this.publishedDate = book.getPublishedDate();
this.status = book.getStatus();
this.location = book.getLocation();
}
}
# UserBookController
- GET /api/v1/books 로 요청.
- 파라미터로 page, size를 받음. 각 기본값이 0과 10.
- Service 계층으로 page, size를 전달함.
- 결과는 Page<UserBookListResDTO> 형태로 저장.
- 클라이언트 측으로 성공메시지와 결과를 ApiResponse.success()로 감싸서 응답.
** 변경사항 없음
@GetMapping()
public ResponseEntity<?> allListBooks(
@RequestParam(value = "page", defaultValue = "0") int page,
@RequestParam(value = "size", defaultValue = "10") int size) {
// 서비스로직
Page<UserBookListResDTO> responseDTO = userBookService.allListBooks(page, size);
// 성공메시지
String message = messageProvider.getMessage(BookSuccessCode.BOOK_LIST_FETCHED.getMessage());
// 응답
return ResponseEntity
.status(BookSuccessCode.BOOK_LIST_FETCHED.getHttpStatus())
.body(ApiResponse.success(
BookSuccessCode.BOOK_LIST_FETCHED,
message,
responseDTO));
}
# UserBookService
- PageRequest.of(page, size)로 페이징을 정의하고 Pageable 형태로 저장.
- bookRepository.findAll(pageable)로 설정된 페이징으로 도서 전체 목록을 조회하여 Page<Book> 형태로 저장.
- Book을 <UserBookListResDTO>로 형변환 후 new PageResponse<>() 객체로 생성하여 Controller로 반환.
** List 형태로 형변환 했던 것을 삭제하고 Page<UserBookListResDTO>로 바로 형변환 하도록 수정.
public Page<UserBookListResDTO> allListBooks(int page, int size) {
// 페이징 정의
Pageable pageable = PageRequest.of(page, size);
// Book 조회 후 UserBookListResDTO로 변환
Page<Book> result = bookRepository.findAll(pageable);
Page<UserBookListResDTO> pageDTO = result.map(UserBookListResDTO::new);
// 반환
return pageDTO;
}
< 공용: 도서 상세 조회 >
# UserBookDetailResDTO
- 도서 상세 조회 응답 DTO
- 도서 고유번호, 제목, 저자, 출판사, 출판일, 상태, 위치, 설명 (id, title, author, publisher, publishedDate, status, location, description)
** 변경사항 없음
@Getter
public class UserBookDetailResDTO {
private Long id;
private String title;
private String isbn;
private String author;
private String publisher;
private LocalDate publishedDate;
private BookStatus status;
private String location;
private String description;
public UserBookDetailResDTO(Book book) {
this.id = book.getId();
this.title = book.getTitle();
this.isbn = book.getIsbn();
this.author = book.getAuthor();
this.publisher = book.getPublisher();
this.publishedDate = book.getPublishedDate();
this.status = book.getStatus();
this.location = book.getLocation();
this.description = book.getDescription();
}
}
# UserBookController
- GET /api/v1/books/{bookId} 로 요청.
- 파라미터로 booId 전달받음.
- Service 계층으로 bookId를 전달함.
- 결과는 Page<UserBookDetailResDTO> 형태로 저장.
- 클라이언트 측으로 성공메시지와 결과를 ApiResponse.success()로 감싸서 응답.
** 변경사항 없음
@GetMapping("/{bookId}")
public ResponseEntity<?> detailBook(@PathVariable("bookId") Long bookId) {
// 서비스 로직
UserBookDetailResDTO responseDTO = userBookService.detailBook(bookId);
// 성공 메시지
String message = messageProvider.getMessage(BookSuccessCode.BOOK_FETCHED.getMessage());
// 응답
return ResponseEntity
.status(BookSuccessCode.BOOK_FETCHED.getHttpStatus())
.body(ApiResponse.success(
BookSuccessCode.BOOK_FETCHED,
message,
responseDTO));
}
# UserBookService
- bookRepository.findById(bookId)로 도서 조회를 하여 도서가 있으면 Book 형태로 저장하고, 없다면 BookErrorCode.BOOK_NOT_FOUND 예외를 발생 시킴.
- Book 기반으로 UserBookDetailResDTO 객체를 생성하여 Controller로 반환.
** 변경사항 없음
public UserBookDetailResDTO detailBook(Long bookId) {
// bookId 조회 및 예외 처리
Book book = bookRepository.findById(bookId)
.orElseThrow(() -> new BaseException(BookErrorCode.BOOK_NOT_FOUND));
// 반환
return new UserBookDetailResDTO(book);
}
< 공용: 도서 검색 >
# UserBookSearchResDTO
- 도서 검색 응답 DTO
- 도서 고유번호, 제목, isbn, 저자, 출판사, 출판일, 상태, 위치 (id, title, isbn, author, publisher, publishedDate, status, location)
** 변경사항 없음
@Getter
public class UserBookSearchResDTO {
private Long id;
private String title;
private String isbn;
private String author;
private String publisher;
private LocalDate publishedDate;
private BookStatus status;
private String location;
public UserBookSearchResDTO(Book book) {
this.id = book.getId();
this.title = book.getTitle();
this.isbn = book.getIsbn();
this.author = book.getAuthor();
this.publisher = book.getPublisher();
this.publishedDate = book.getPublishedDate();
this.status = book.getStatus();
this.location = book.getLocation();
}
}
# UserBookController
- GET /api/v1/books/search 로 요청.
- 파라미터로 type, keyword, page, size 전달받음.
- Service 계층으로 type, keyword, page, size를 전달함.
- 결과는 PageResponse<UserBookSearchResDTO> 형태로 저장.
- 클라이언트 측으로 성공메시지와 결과를 ApiResponse.success()로 감싸서 응답.
** PageResponse 형태로 결과 받음
@GetMapping("/search")
public ResponseEntity<?> searchBooks(
@RequestParam("type") BookSearchType type,
@RequestParam("keyword") String keyword,
@RequestParam(value = "page", defaultValue = "0") int page,
@RequestParam(value = "size", defaultValue = "10") int size) {
// 서비스 로직
PageResponse<UserBookSearchResDTO> responseDTO = userBookService.searchBooks(type, keyword, page, size);
// 성공 메시지
String message = messageProvider.getMessage(BookSuccessCode.BOOK_LIST_FETCHED.getMessage());
// 반환
return ResponseEntity
.status(BookSuccessCode.BOOK_LIST_FETCHED.getHttpStatus())
.body(ApiResponse.success(
BookSuccessCode.BOOK_LIST_FETCHED,
message,
responseDTO));
}
# UserBookService
- PageRequest.of(page,size)를 사용하여 페이징을 정의하여 Pageable 형태로 저장.
- Page<Book>타입의 변수 생성.
- switch문을 사용하여 type(ALL, TITLE, AUTHOR)별 Repository.메서드 실행
- Book 형태로 받은 결과를 UserBookSearchResDTO로 맵핑한 다음 Controller로 반환할 때 PageResponse<> 객체로 생성하여 반환한다.
** PageResponse 활용
public PageResponse<UserBookSearchResDTO> searchBooks(BookSearchType type, String keyword, int page, int size) {
// 페이징 정의
Pageable pageable = PageRequest.of(page, size);
// Page<Book> 타입의 변수 생성
Page<Book> result;
// 타입 switch문으로 case 실행
switch(type) {
case ALL:
result = bookRepository.findByTitleContainingIgnoreCaseOrAuthorContainingIgnoreCase(keyword, keyword, pageable);
break;
case TITLE:
result = bookRepository.findByTitleContainingIgnoreCase(keyword, pageable);
break;
case AUTHOR:
result = bookRepository.findByAuthorContainingIgnoreCase(keyword, pageable);
break;
default:
throw new IllegalArgumentException("Unexpected search type: " + type);
}
// Book -> UserBookSearchResDTO로 형변환
Page<UserBookSearchResDTO> pageDTO = result.map(UserBookSearchResDTO::new);
// 반환
return new PageResponse<>(pageDTO);
}