Fetch Join
Closed this issue · 0 comments
yoon-youngjin commented
Fetch Join
현재 상황
상품아이디(Item->id), 상품명(Item->itemNm), 상태(Item->itemSellStatus), 등록자(Item->createdBy), 등록일(Item->regTime)
모두 Item에서 가져올 수 있는 데이터 -> Item과 연관된 Member를 조회할 필요가 없음
따라서 지연로딩으로 설정하였기 때문에 SELELT SQL에는 item에 관한 쿼리문만 존재한다.
**등록자 이름(Item -> Member -> name)**과 같은 Item에 연관된 필드에서 데이터를 조회해야 하는 경우에는?
변경된 상황
지연로딩으로 설정하였기 때문에 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);
}
}
QueryDsl에 fetch join을 적용하고 실행하면 하나의 SELECT SQL안에 inner join을 통해서 Item과 연관된 Member를 한 번에 가져옴을 볼 수 있다.