PeerGroup-JavaSpringBoot/SpringBootStudy

Fetch Join

Closed this issue · 0 comments

Fetch Join

현재 상황

image

상품아이디(Item->id), 상품명(Item->itemNm), 상태(Item->itemSellStatus), 등록자(Item->createdBy), 등록일(Item->regTime)

모두 Item에서 가져올 수 있는 데이터 -> Item과 연관된 Member를 조회할 필요가 없음

따라서 지연로딩으로 설정하였기 때문에 SELELT SQL에는 item에 관한 쿼리문만 존재한다.

image

**등록자 이름(Item -> Member -> name)**과 같은 Item에 연관된 필드에서 데이터를 조회해야 하는 경우에는?

변경된 상황

image

image

지연로딩으로 설정하였기 때문에 SELECT SQL에 Item과 연관된 Member를 조회하기 위한 쿼리문이 하나 더 생긴걸 확인할 수 있다.

만약 연관된 데이터가 굉장히 많고 모든 연관된 데이터에서 데이터를 조회해야 한다면 연관된 데이터의 개수만큼 SELECT SQL이 추가될 것이다.

Fetch Join 적용하기

public class ManageItemRepositoryImpl implements ManageItemRepository {
    
   ...
    @Override
    public Page<Item> getAdminItemPage(ItemSearchDto itemSearchDto, Pageable pageable) {

        List<Item> content = queryFactory
                .selectFrom(QItem.item)
                /**
                 * fetch join 적용 
                 */
                .join(QItem.item.member, QMember.member).fetchJoin() 
                .where(regDtsAfter(itemSearchDto.getSearchDateType()),
                        searchSellStatusEq(itemSearchDto.getSearchSellStatus()),
                        searchByLike(itemSearchDto.getSearchBy(),
                                itemSearchDto.getSearchQuery()))
                .orderBy(QItem.item.id.desc())
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetch();

        int totalSize = queryFactory
                .selectFrom(QItem.item)
                .where(regDtsAfter(itemSearchDto.getSearchDateType()),
                        searchSellStatusEq(itemSearchDto.getSearchSellStatus()),
                        searchByLike(itemSearchDto.getSearchBy(),
                                itemSearchDto.getSearchQuery()))
                .fetch().size();

        return new PageImpl<>(content, pageable, totalSize);
    }
}

image

QueryDsl에 fetch join을 적용하고 실행하면 하나의 SELECT SQL안에 inner join을 통해서 Item과 연관된 Member를 한 번에 가져옴을 볼 수 있다.