ProductRepository
selectList 반환 객체로 Tuple을 사용할 것이다.
여러 객체를 한번에 sql로 호출하기 위해 많이 사용한다. (특히 Collection 필드 가져올 때)
Page 객체 내 제네릭 타입으로는 일단 Object
를 선정해주고
public interface ProductRepository extends JpaRepository<Product, Long> ,
ProductSearch {
@EntityGraph(attributePaths = {"imageList"}) // imageList 를 product 가져올시 같이 가져옴
@Query("select p from Product p where p.pno = :pno and p.delFlag = false")
Optional<Product> selectOne(@Param("pno") Long pno);
@Modifying
@Query("update Product p set p.delFlag = true where p.pno = :pno")
void updateToDelete(@Param("pno") Long pno);
@Query("select p, pi from Product p left join p.imageList pi where pi.ord = 0 and p.delFlag = false")
Page<Object[]> selectList(Pageable pageable);
}
ProductSearch
public interface ProductSearch {
PageResponseDto<ProductResponse> searchList(PageRequestDto pageRequestDto);
}
QuerydslRepositorySupport 사용 ProductSearch 구현체를 보자면,
ProductSearchImpl
@Slf4j
public class ProductSearchImpl extends QuerydslRepositorySupport implements ProductSearch {
public ProductSearchImpl() {
super(Product.class);
}
@Override
public PageResponseDto<ProductResponse> searchList(PageRequestDto pageRequestDto) {
log.info("searchList............");
Pageable pageable = PageRequest.of(
pageRequestDto.getPage() - 1,
pageRequestDto.getSize(),
Sort.by("pno").descending()
);
JPQLQuery<Product> query = from(product);
query.leftJoin(product.imageList, productImage);
query.where(product.delFlag.eq(false));
query.where(productImage.ord.eq(0));
Objects.requireNonNull(getQuerydsl()).applyPagination(pageable, query);
List<Tuple> tupleList = query.select(product, productImage)
.fetch();
long count = query.fetchCount();
log.info("==================================");
log.info("tupleList : " + tupleList);
log.info("tupleList size : " + tupleList.size());
log.info("count : " + count);
return null;
}
}
만들면서 어지럽긴 한데, 기존의 OneToMany 컬렉션 타입의 필드를 fetch join 으로 한번에 가져오는 방식이 어렵다면, 이 방법도 권해본다. 개인적으로 querydsl을 추천...