티스토리 뷰
메인 페이지 만들기
ItemController
기존에는 메인으로만 돌아가는 역할을 했다면, 지금은 무언가를 연결해서 보여주는 로직으로 변모
@Controller
@RequiredArgsConstructor
public class MainController {
  private final ItemService itemService;
  @GetMapping(value = "/")
  public String main(ItemSearchDto itemSearchDto, Optional<Integer> page, Model model) {
    Pageable pageable = PageRequest.of(page.isPresent() ? page.get() : 0, 5);
    if (itemSearchDto.getSearchQuery() == null) {
      itemSearchDto.setSearchQuery("");
    }
    Page<MainItemDto> items = itemService.getMainItemPage(itemSearchDto, pageable);
    System.out.println(items.getNumber() + "!!!!!");
    System.out.println(items.getTotalPages() + "#####");
    model.addAttribute("items", items);
    model.addAttribute("itemSearchDto", itemSearchDto);
    model.addAttribute("maxPage", 5);
    return "main";
  }
--> 메인에서 보여줄 아이템도 페이징 처리를 해서 특정한 개수만큼만 들고 온 다음 화면에 보여줄 것이고 화면에 보여줄 것이니까 모델이 필요하다.
화면에 보여줄 때 아이템 정보 전달할 Dto도 생성 Item을 그대로 들고다니진 않음.
@Getter
@Setter
public class MainItemDto {
  private Long id;
  private String itemNm;
  private String itemDetail;
  private String imgUrl;
  private Integer price;
  @QueryProjection // 쿼리dsl 결과 조회 시 MainItemDto 객체로 바로 오도록 활용.
  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;
  }
}
Projection은 SQL에서 select * from 처럼 전부를 가지고 오는 게 아니라
일부만 가지고 올 때 쓴다. select id, itemNm from ~ 등...
이 두 개를 하나로 묶어서 그 객체째로 받는 것.
여기선   private Long id;
  private String itemNm;
  private String itemDetail;
  private String imgUrl;
  private Integer price; 이 다섯개를 하나로 묶어서, 각각 받는 것이 아니라 하나의 객체에 쿼리dsl이 매핑한 다음에 리턴을 준다는 뜻.
그 코드가 바로 여기
ItemRepositoryCustomImpl
  @Override
  public Page<MainItemDto> getMainItemPage(ItemSearchDto itemSearchDto, Pageable pageable) {
    QItem item = QItem.item;
    QItemImg itemImg = QItemImg.itemImg;
    // QMainItemDto @QueryProjection을 허용하면 DTO로 바로 조회 가능
    QueryResults<MainItemDto> results = queryFactory.select(new QMainItemDto(item.id, item.itemNm, item.itemDetail
        , itemImg.imgUrl, item.price))
    // join 내부조인 .repImgYn.eq("Y") 대표이미지만 가져온다.
        .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()).fetchResults();
    List<MainItemDto> content = results.getResults();
    long total = results.getTotal();
    return new PageImpl<>(content, pageable, total);
  }
QMainItemDto(item.id, item.itemNm, item.itemDetail, itemImg.imgUrl, item.price) 이 다섯개를
MainItemDto라는 이름으로 객체에 담아줘.
그래서 result가 MainItemDto.
이게 아니었으면 이 다섯개를 리스트로 받거나 배열로 받아서 하나씩 쪼개서 다시 dto 객체를 만들고 세팅해주는 지리한 과정을 일일이 했어야 한다.
ItemService
@Transactional(readOnly = true)
  public Page<MainItemDto> getMainItemPage(ItemSearchDto itemSearchDto, Pageable pageable) {
    return itemRepository.getMainItemPage(itemSearchDto, pageable);
  }
사실 클래스 위에 어노테이션으로 @Transactional이 붙어 있는데, true라는 다른 값이기 때문에 쓴 건데, 이걸 쓰면 급진적 성능향상을 기대할 수 있음.
readOnly가 true면 읽기 전용이라 조회만 할 거니까 snapshot을 기억해두지 않아도 된다.
'[개발] - Spring > SpringShop' 카테고리의 다른 글
| shop 구현 (13) 주문 기능 구현 (1) | 2023.07.21 | 
|---|---|
| shop 구현 (12) 상품 상세 페이지 (0) | 2023.07.20 | 
| shop 구현 (10) 상품 관리하기 페이지 (0) | 2023.07.15 | 
| shop 구현 (9) 특이한 상속구조 (0) | 2023.07.14 | 
| shop 구현 (8) 상품 수정하기 / 변경감지 (0) | 2023.07.14 |