아이템 전체 조회 API - 좋아요 표시 관련 N+1

아이템 전체 조회 API : item 검색(item, idol_member, idol_group, user, category_item, image 연관 관계)과 user_item(좋아요)를 개인화(user_item.user_id)하여 아이템에 좋아요를 했는지 표시하는 기능을 구현해야 했다.

복잡해서 MySQL 기준 쿼리로 먼저 짰다.

select ui.item_id, count( if(ui.user_id=<사용자 id>, ui.user_id, NULL)) from user_item ui
group by ui.item_id;

문제 상황 : 아이템 전체 조회 페이지(홈)에서 복잡한 연관 관계로 인해 N+1 쿼리 이슈 발생

따라서 엔티티 그래프에 미리 추가하기 위해(?) 조인 한방 쿼리를 날림.

  • 수정 전 - (item 검색), (idol_member 검색), (idol_group 검색), (user 검색), (category_item 검색), (image 검색)

      queryFactory.select(item, new CaseBuilder()
                      .when(userItem.user.id.eq(userId)).then(1L).otherwise(0L).sum())             .from(item)
                      .groupBy(item)
                      .leftJoin(userItem).on(userItem.item.id.eq(item.id));
    
  • 수정 후 - (item, idol_member, idol_group, user, category_item 검색), (image 검색)

      queryFactory.select(item, new CaseBuilder()
      								.when(userItem.user.id.eq(userId)).then(1L).otherwise(0L).sum(), idolMember, idolGroup, categoryItem, user)
      								.groupBy(item, idolMember, idolGroup, categoryItem, user)
                      .leftJoin(userItem).on(userItem.item.id.eq(item.id))
                      .join(idolMember).on(item.idolMember.eq(idolMember))
                      .join(idolGroup).on(idolMember.idolGroup.eq(idolGroup))
                      .join(categoryItem).on(item.categoryItem.eq(categoryItem))
                      .join(user).on(item.user.eq(user));