작성
·
39
0
저번에도 같은 질문을 올렸다가 질문이 두서가 없다보니 여쭤보려고 한 것을 잘못 물어본거같아서 다시 질문드립니다. Spring Data JPA를 바탕으로 토이프로젝트를 개발하고있고 Pageable 인터페이스를 활용하고 있습니다.
프로젝트에서 Item(품목)의 하위 개념으로 Product(제품)을 가지고 있습니다.(1:N - 품목 하나에 대해 여러개의 제품을 등록 할 수 있음)
예를 들어 핸드폰이라는 Item(품목) 정보를 등록하고, 그 품목에 대한 Product(제품) ( 이를테면 아이폰10, 갤럭시S25, 샤오미)의 정보들을 등록합니다.
이때 특정 품목(itemId)을 클릭하면 해당 품목에 대한 정보와 내가 등록한 product 리스트가 띄어지도록 하는 api 기능을 구현하려 했습니다. 처음에는 요청이 item컨트롤러로 디스패치하고, product와 itemId를 기준으로 패치조인하여 데이터를 받아오는 식으로 구현을 했는데.. product리스트를 불러오는 과정에서 페이징을 하고자 기존의 로직을 수정하니, 메인i 테이블인 item을 기준으로 페이징이 되는 문제가 발생했습니다.
// page처리 시 문제가 발생하는 respository method
@Query(value = "SELECT DISTINCT i FROM Item i LEFT JOIN FETCH i.productList WHERE i.id = :itemId",
countQuery = "SELECT COUNT(p) FROM Product p WHERE p.item.id = :itemId")
Page<Item> findWithProductsByItemId(@Param("itemId") long itemId, Pageable pageable);
그래서 제가 생각한 두가지 안이 있는데 이중에 어떤 것으로 개발해야할지 판단이 잘 서지않아 질문드립니다.
1) 응용계층에서 item에 대한 정보를 불러오는 item서비스 호출 + 위 item에 해당되는 product 리스트 정보들을 paging 하여 불러오는 페이징하여 불러오는 product서비스 호출
2) product를 메인으로 item과 n:1 패치조인하는 메소드를 productRepository에서 생성.
1번 방법이 맞는 것 같지만,, paging으로 데이터를 불러올 때마다 item쿼리를 한번씩 날려야하는게 비효율적인거 같기도하고,, 2번으로 하자니... 구현하고자 하는 기능은 item을 메인으로 product 목록을 불러오는 것인데,, 실제 동작은 Product가 메인으로(Product컨트롤러로 디스패치) 처리가 되다보니 이렇게 해도 될까 하는 의문이 들었습니다.
이런 상황에서는 어떤 식으로 구현을 하는게 좋을지요. 고견을 여쭙니다 ㅠㅠ
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
인생은회전목마님이 고민하시는 상황에 대한 조언을 드리겠습니다.
Spring Data JPA에서 페치 조인과 페이징을 함께 사용하기란 복잡할 수 있습니다. 두 가지 제안해 주신 방법 중에서 각각의 장단점을 고려해 보겠습니다.
첫 번째 방법 (Item을 메인으로 하여 Product 페이징):
두 번째 방법 (Product를 메인으로 하여 Item과 N:1 페치 조인):
추천 방식:
각 방법의 장단점을 고려할 때, 애플리케이션의 구조와 장기적인 유지보수성을 고려해야 합니다. 첫 번째 방법이 응용계층에서 복합적인 로직을 처리하고, 데이터베이스 쿼리 수가 늘어날 수 있다는 단점이 있지만, 도메인 로직의 명확성을 유지할 수 있습니다.
해결 방법으로는, Lazy loading을 사용해 필요할 때만 관련 데이터를 가져오도록 최적화하거나, 필요에 따라 Redis와 같은 캐시 솔루션을 사용해 중복 쿼리를 줄이는 방법도 고려해 보실 수 있습니다.
추가로, JPA 2.1 이상에서는 “Entity Graph”를 통해 특정 연관 관계를 쉽게 가져올 수 있는 방법도 있으니 참고하시면 좋겠습니다.
이미지를 참고하여 더 구체적이거나 수정이 필요할 수 있는 부분이 있으면 알려주세요. 더 나은 방법을 찾을 수 있도록 함께 고민하겠습니다. 😊
관련 문서 링크:
- Spring Data JPA 페이징 및 스크롤링
- 페이징 고려사항