티스토리 뷰
Page<Entity>를 꺼내는 방법은 정말 쉽다. 이미 JPA에 의해 다 구현이 되어있으므로 그냥 파라미터로 Pageable을 넘겨서 Page<Entity>를 리턴받으면 끝이다.
하지만 이 Entity를 DTO로 변환시켜서 넘겨야 하는건 생각보다 까다롭다.
Page 인터페이스는 List<Entity>, Pageable, totalElements 3가지를 가지고 있는 형태라고 볼 수 있다.
하지만 Page<>로 넘기지않고 PageImpl을 사용한다거나 하면 boundary 값 처리를 직접 해줘야 하는 등 귀찮은 일이 생긴다.
기본적인 구현 방법은 람다식을 이용하여 돌면서 값을 converting 해주면 된다.
여기서 중요한 점은 이때 사용되는 map 함수는 Page 인터페이스의 map이다.
선택하려고 해서 선택할 수 있는 것은 아니지만 map은 Stream의 map도 있고 Optional의 map도 있다.
public Page<ItemResponse> showItemsBySeller(User user, Pageable pageable) {
Seller seller = sellerRepository.findByUserIdAndIsActivatedTrue(user.getId())
.orElseThrow(() -> new SellerNotFoundException("판매자 권한이 없습니다"));
return itemRepository.findBySellerId(seller.getId(), pageable)
.map(item -> ItemResponse.builder()
.id(item.getId())
.name(item.getName())
.price(item.getPrice())
.build());
Page<Item> findBySellerId(Long id, Pageable pageable);
위에서 사용되는 findBySellerId()는 단순히 Page<Entity>를 반환하는 메서드였다.
이때 Optional을 사용하여 null-safe하게 처리하고 싶으면 어떻게 해야할까?
Optional<Page<Entity>>을 리턴해야 할까 Page<Optional<Entity>>을 리턴해야할까?
둘다 람다식을 돌며 처리해야 하는 것은 같다. 하지만 Optional의 처리 방식을 생각하면 Optional<Page<Entity>>의 형태로 반환하는 것이 바람직하다고 생각한다.
코드는 다음과 같다.
public Page<ItemResponse> searchItemsByKeyword(String keyword, Pageable pageable) {
return itemRepository.findByNameContaining(keyword, pageable)
.map(items -> items.map(item -> ItemResponse.builder()
.id(item.getId())
.name(item.getName())
.price(item.getPrice())
.build()))
.orElseThrow(() -> new ItemNotFoundException("해당 키워드에 맞는 상품이 없습니다"));
Optional<Page<Item>> findByNameContaining(@Param("q") String name, Pageable pageable);
이때 위에서 말했던 map의 차이점이 여기에서 나온다.
첫번째의 map이 Optional을 처리해주는 map이고
이 map에서 한 번 더 들어가서 사용되는 map이 Page의 map이다.
2번의 map처리를 nested 형태로 처리해줘야 하는 것을 명심해야 하며
Optional<Page<Entity>>의 형태로 만들었기에 마지막에 한번의 Optional 처리만 해주면 된다.
익숙해지면 편리하긴 한데 성능상의 문제가 생기지 않을까 걱정되기에성능 테스트를 돌려봐야 할 것으로 생각됨
'Spring' 카테고리의 다른 글
스프링부트에서 옵션을 구현하는 방법 (0) | 2022.06.03 |
---|---|
아임포트 스프링부트로 결제 연동하기 (1) (1) | 2022.06.01 |
하나의 form에서 여러개 field의 file을 받는 방법 (0) | 2022.05.29 |
로그인 이후에 이전 페이지 스크롤 위치로 이동하는 방법 구현하기 (0) | 2022.05.26 |
스프링 시큐리티로 로그인 이후에 현재 페이지로 되돌아오는 방법 (0) | 2022.05.26 |
- Total
- Today
- Yesterday
- lunarvim
- 배포
- ModelAttribute
- 루나빔
- Dap
- neovim
- RequestBody
- 도커
- 레디스
- RequestPart
- 아키텍처
- JavaScript
- IDE
- RequestParam
- vim
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |