인프런 커뮤니티 질문&답변

이동명님의 프로필 이미지
이동명

작성한 질문수

실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화

API 개발 고급 정리

질문이 있습니다!

작성

·

393

0

안녕하세요. 게시판의 댓글을 계층형으로 짜려고 시도하고 있는데 헷갈려서 복습겸 다시 강의 듣다가 질문드립니다.

우선 처음 게시판을 조회할때 최상위 부모 댓글들을 페이징 처리하여 가져옵니다.

그 후 최상위 부모 댓글의 자식들도 페이징 처리하여 가져오고 싶은데 그냥 페이징으로 가져오면 자식들의 수많큼 쿼리를 날리게 되어 현재 강의의 방식대로 가져오는 방법을 사용해보았는데 이 방법은 특정 ID들에 속한 값들을 모두 조회한 후 gropingBy를 통해 분리했기 때문에 페이징이 불가능한거 같은데 제가 잘못이해하고 있는건가요?

혹은 제가 접근법이 잘못되었는지 궁금해서 질문드립니다.

감사합니다.

답변 5

2

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 동명님

아쉽지만 원하시는 방법은 SQL에서 지원하지 않습니다. 따라서 JPQL로도 문제를 해결할 수 없습니다.

결국 각각의 orderId 각각 마다 각각 쿼리를 따로 실행하셔야 합니다.

실무에서 트래픽 상황에 따라 다음과 같은 방법으로 해결합니다.

1. 성능이 중요하지 않은 경우: 내부 시스템에서 사용하는 어드민이라면 그냥 쿼리를 orderId 수 만큼 실행합니다.

2. 성능이 중요한 경우: 첫번째 페이지만 가지고 있는 데이터를 별도의 캐시에 각각 말아둡니다. 예를 들어서 a,b,c,가 있으면 a,b,c 각각 첫 10건의 데이터만 따로 가지고 있는 것이지요. 그리고 이후에 a에 더보기를 누르면 a 데이터만 테이블의 다음 페이지에서 추가로 조회합니다. 보통 첫 페이지를 보는 유저는 매우 많지만, 그 다음 더보기를 누르는 유저는 상대적으로 적기 때문에 첫 페이지를 캐시에 잘 말아두는 방법을 활용하면 좋습니다.

감사합니다^^

1

이동명님의 프로필 이미지
이동명
질문자

아 그렇군요! 친절한 답변 감사합니다. 참고하겠습니다!

0

김영한님의 프로필 이미지
김영한
지식공유자

네^^! 좋은하루 되세요

0

이동명님의 프로필 이미지
이동명
질문자

아 제가 아직  많이 부족해서 설명을 제대로 못한거같네요.

이 부분에서 where in 절을 사용하여 orderIds들의 값들을 가져오는데 가져올때 orderId 하나하나마다 가져올 데이터 개수를 제한할 수 있는지 물어본거였어요.

그래서 그냥 일단 다 가져오고 개수에 맞게 짤라서 해결했습니다!

private Map<Long, List<OrderItemQueryDto>> findOrderItemMap(List<Long> orderIds) {
List<OrderItemQueryDto> orderItems = em.createQuery(
"select new jpabook.jpashop.repository.order.query.OrderItemQueryDto" +
"(oi.order.id, i.name, oi.orderPrice, oi.count)" +
" from OrderItem oi" +
" join oi.item i" +
" where oi.order.id in :orderIds", OrderItemQueryDto.class)
.setParameter("orderIds", orderIds)
.getResultList();

return orderItems.stream()
.collect(Collectors.groupingBy(OrderItemQueryDto::getOrderId));
}

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요 동명님^^

정확히 어떤 것을 원하시는지 제가 잘 이해하지 못해서 그런데, 매우 구체적인 예제로 다시 한번 설명 부탁드릴께요^^!

이동명님의 프로필 이미지
이동명

작성한 질문수

질문하기