[JPA] 스트림 사용 GetMapping

박연주·2022년 6월 30일
0

JPA

목록 보기
1/8
# v1 엔티티 노출 버전
	@GetMapping("/api/v1/members")
    public List<Member> getMemberV1() {
        return memberService.findMembers();
    }

# v2 리스트를 감싸는 버전
    @GetMapping("/api/v2/members")
    public Result getMemberV2() {
        List<Member> findMembers = memberService.findMembers();
        List<MemberDto> collect = findMembers.stream()
                .map(m -> new MemberDto(m.getName()))   // member를 new MemberDto로 변환
                .collect(Collectors.toList());    		// 리스트로 담기
        return new Result(collect)
    }
    
    @Data
    @AllArgsConstructor
    static class Result<T> {
        private T data;   -> data로 감싸줌으로써 확장성 증가
    }

    @Data
    @AllArgsConstructor
    static class MemberDto {
        private String name;
    }
    
    GET localhost:8080/api/v2/members
    {
      "data": [
          {
              "name": "userA"
          },
          {
              "name": "userB"
          },
          {
              "name": "stream-연습"
          }
       ]
    }
    
    # count 를 추가하고 싶으면 Result<T>에 추가 후 return 값에도 추가
    private int count;
    
    return new Result(collect.size(), collect)
    
    {
      "count" : 3,
      "data": [
          {
              "name": "userA"
          },
          {
              "name": "userB"
          },
          {
              "name": "stream-연습"
          }
       ]
    }


API 개발 고급

간단한 Order 조회
1. 엔티티 직접 조회 V1
2. DTO로 담는 조회 V2 - 너무 많은 쿼리 호출(order, member, delivery)

/**
 * xToOne - 성능 최적화
 * Order
 * Order -> Member
 * Order -> Delivery
 */

# 멤버와 딜리버리 정보 가져오기  - 엔티티 직접조회
 @GetMapping("/api/v1/simple-orders")
    public List<Order> getOrdersV1() {
        List<Order> all = orderRepository.findAllByString(new OrderSearch());
        return all;
    }
    
    -> 양방향 연관관계로 무한 루프 돔
	-> 양방향 매핑에서 한 쪽은 @JsonIgnore 처리 필요함
    -> 다른 정보까지 노출

@GetMapping("/api/v1/simple-orders")
    public List<Order> getOrdersV1() {
        List<Order> all = orderRepository.findAllByString(new OrderSearch());
        for (Order order : all) {     		// getMember() 까지는 proxy 개체
            order.getMember().getName();    // getName() Lazy 강제 초기화
        }
        return all;
    }

@GetMapping("/api/v3/simple-orders")
public List<SimpleOrderDto> getOrderV3() {
    List<Order> orders = orderRepository.findAllWithMemberDelivery();
    List<SimpleOrderDto> result = orders.stream()
            .map(o -> new SimpleOrderDto(o))
            .collect(Collectors.toList());
    return result;
}
// 주문 2개
// N + 1 -> 1 + N(2) = 1 + 회원 N + 배송 N = 5 (첫번째 쿼리의 결과로 N번만큼 쿼리가 추가 실행되는 것)    
    
    
public List<Order> findAllWithMemberDelivery() {
        return em.createQuery(
                "select o from Order o" +
                " join fetch o.member" +
                " join fetch o.delivery d", Order.class
        ).getResultList();
}
profile
하루에 한 개념씩

0개의 댓글