# 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-연습"
}
]
}
간단한 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();
}