1. 문제 상황
요구사항
기존 고객 조회 API에 다음 정보를 추가해야 했다.
- 총 주문 수
- 총 구매 금액
2. 처음 구현한 방법
처음에는 OrderRepository에 메서드를 만들었다.
countByCustomerId(customerId)
sumTotalPriceByCustomerId(customerId)
그리고 CustomerService에서
orderRepository.countByCustomerId(customer.getId());
orderRepository.sumTotalPriceByCustomerId(customer.getId());
를 호출하여 응답 DTO에 담았다.
장점
- 구현이 간단하다.
- 이해하기 쉽다.
3. 고민했던 부분
하지만 고객 목록 조회에서는
고객이 100명이라면?
고객마다
count()
sum()
를 각각 실행하게 된다.
즉
고객 조회 1번
+
count 100번
+
sum 100번
처럼 많은 쿼리가 발생할 수 있다는 점이 아쉬웠다.
4. 리팩토링을 고민했던 이유
그래서
JPQL GROUP BY
를 이용해서 한 번의 조회에서
- 고객 정보
- 주문 개수
- 주문 금액
까지 모두 가져오는 방법을 고민했다.
예를 들어
Customer
LEFT JOIN
Order
GROUP BY Customer
방식이다.
하지만 프로젝트 일정상 기존 구현을 먼저 완료하고,
이후 성능 개선 방향으로 리팩토링하는 것으로 결정하였다.
그런데!! 오늘 수업에서 JOIN FETCH 로도 이걸 해결할 수 있다는걸 알게되었다..!!!
그래서 나중에 JOIN FETCH에 대해서 공부해봐야할듯
5. 새롭게 알게 된 점
① Spring Data JPA 메서드 규칙
필드명이
status
이면
countByStatus(...)
처럼 메서드 이름만으로도 조회가 가능하다.
굳이 JPQL을 작성하지 않아도 되는 경우가 많다는 것을 알게 되었다.
② COALESCE
SUM은 조회 결과가 없으면
null
을 반환한다. 그래서
COALESCE(SUM(...), 0)
을 사용하면 null 대신
0
을 반환할 수 있다는 것을 배웠다.
회고
이번 구현을 하면서 단순히 기능을 만드는 것이 아니라,
- Repository 메서드 설계
- 조회 성능
- JPQL과 메서드 쿼리의 선택 기준
까지 함께 고민해볼 수 있었다.
다음에는 GROUP BY 또는 JOIN FETCH로 한 번의 쿼리로 개선해보고 싶다.
'TIL' 카테고리의 다른 글
| 싱글톤(Singleton) 패턴이란? (0) | 2026.07.23 |
|---|---|
| JPA N+1 문제란? (왜 생기고 어떻게 해결할까?) (0) | 2026.07.15 |
| [Spring] MVC에서 자주 사용하는 객체와 어노테이션 정리 (0) | 2026.07.08 |
| Java 리스트(List) 활용 & 반복문 리팩토링 (0) | 2026.06.23 |
| 람다(Lambda)와 스트림(Stream) 간단 정리 (0) | 2026.06.22 |