이번은 쇼핑몰 메인 화면에 등록된 상품들을 하나씩 보여주도록 하겠습니다. 보여줄 값으로 상품 이름, 상세정보, 가격, 이미지를 주려고 합니다. 조회하려는 엔티티 값이 item과 itemImg 두 개여서 한번에 값을 받을 MainItemDto를 생성하고 QueryDsl의 @QueryProjection을 사용해서 한번에 조회하겠습니다.
@QueryProjection을 사용하면 QueryDsl을 join을 써서 반환값을 Dto 객체에 맞게 받아올 수 있습니다. 사용하기 전 꼭 @QueryProjection을 사용할 생성자를 QEntity로 만들어야 합니다.
@Getter @Setter
public class MainItemDto {
private Long id;
private String itemNm;
private String itemDetail;
private String imgUrl;
private Integer price;
@QueryProjection
public MainItemDto(Long id, String itemNm, String itemDetail, String imgUrl, Integer price) {
this.id = id;
this.itemNm = itemNm;
this.itemDetail = itemDetail;
this.imgUrl = imgUrl;
this.price = price;
}
}
@QueryProjection를 사용하면 쿼리문 하나를 사용해서 Repository에서 바로 Dto 객체를 반환해주는 메서드를 만들 수 있습니다.
1. 먼저 사용할 QItem, QItemImg 를 만들어 놓습니다.
2. queryFactory의 select문에 객체로 반환할 QMainItemDto를 생성자를 선언하고 매개변수들을 Dto 필드값에 맞게 QEntity 필드를 지정해줍니다.
3. join은 inner join을 의미하며, itemImg 내부의 FK인 item.id를 사용해서 item을 조인합니다.
4. where문에 대표이미지, 검색 값을 넣어줍니다.
@Override
public Page<MainItemDto> getMainItemPage(ItemSearchDto itemSearchDto, Pageable pageable) {
QItem item = QItem.item;
QItemImg itemImg = QItemImg.itemImg;
List<MainItemDto> results = queryFactory
.select(
new QMainItemDto(
item.id,
item.itemNm,
item.itemDetail,
itemImg.imgUrl,
item.price)
)
.from(itemImg)
.join(itemImg.item, item)
.where(itemImg.repImgYn.eq("Y"))
.where(itemNmLike(itemSearchDto.getSearchQuery()))
.orderBy(item.id.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
long total = results.size();
return new PageImpl<>(results, pageable, total);
}
@Transactional(readOnly = true)
public Page<MainItemDto> getMainItemPage(ItemSearchDto itemSearchDto, Pageable pageable){
return itemRepository.getMainItemPage(itemSearchDto, pageable);
}
@GetMapping("/")
public String main(ItemSearchDto itemSearchDto, Optional<Integer> page, Model model){
Pageable pageable = PageRequest.of(page.isPresent() ? page.get() : 0, 6 );
Page<MainItemDto> items = itemService.getMainItemPage(itemSearchDto, pageable);
model.addAttribute("items", items);
model.addAttribute("itemSearchDto", itemSearchDto);
model.addAttribute("maxPage", 5);
return "main";
}
나머지는 상품관리와 동일합니다.