Spring boot & JPA

Spring Boot - 쇼핑몰 프로젝트 06 (상품 등록 및 조회하기 - 3)

록's 2023. 4. 6. 16:27
728x90
반응형

https://rogi221.tistory.com/177

 

Spring Boot - 쇼핑몰 프로젝트 06 (상품 등록 및 조회하기 - 1)

상품 등록 및 조회하기 상품 등록하기 상품 이미지 엔티티는 이미지 파일명, 원본 이미지 파일명, 이미지 조회 경로, 대표 이미지 여부를 갖도록 설계 대표 이미지 여부가 “Y”인 경우 메인페이

rogi221.tistory.com

 

https://rogi221.tistory.com/179

 

Spring Boot - 쇼핑몰 프로젝트 06 (상품 등록 및 조회하기 - 2)

상품 등록 및 조회하기 - 2 상품 수정하기 상품 등록 후 콘솔창을 보면 insert into item 쿼리문에서 item_id에 들어가는 binding parameter 값 확인 해당 상품 아이디를 이용해서 상품 수정 페이지에 진입 예

rogi221.tistory.com

 

 


상품 등록 및 조회하기 - 3

 

메인화면

  • 등록한 상품을 메인 페이지에서 고객이 볼 수 있도록 구현
  • 메인 페이지 구현도 상품 관리 메뉴 구현과 비슷하며, 동일하게 Querydsl을 사용하여 페이징 처리 및 네비게이션바에 있는 Search 버튼을 이용하여 상품명으로 검색이 가능하도록 구현

 

 

 

  • @QueryProjection을 이용하여 상품 조회 시 DTO 객체로 결과를 받는 예제 진행

메인 페이지 구현하기

com.shop.dto.MainItemDto.java

// MainItemDto.java

package com.shop.dto;

import com.querydsl.core.annotations.QueryProjection;
import lombok.Getter;
import lombok.Setter;

@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을 사용할 때 [maven compile]을 실행해 QDto 파일을 생성

 

 

메인 페이지 상품 리스트 조회 쿼리 작성

com.shop.repository.ItemRepositoryCustom.java

// ItemRepositoryCustom.java

package com.shop.repository;

import com.shop.dto.ItemSearchDto;
import com.shop.dto.MainItemDto;
import com.shop.entity.Item;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import com.shop.dto.MainItemDto;

public interface ItemRepositoryCustom {
    Page<Item> getAdminItemPage(ItemSearchDto itemSearchDto, Pageable pageable);

    Page<MainItemDto> getMainItemPage(ItemSearchDto itemSearchDto, Pageable pageable);
}

 

 

 

com.shop.repository.itemrepositoryCustomImpl.java

// itemrepositoryCustomImpl.java

... 기존 임포트 생략 ...

import com.shop.dto.MainItemDto;
import com.shop.dto.QMainItemDto;
import com.shop.entity.QItemImg;

public class ItemRepositoryCustomImpl implements ItemRepositoryCustom {

... 생략 ...

    private BooleanExpression itemNmLike(String searchQuery) {
        return StringUtils.isEmpty(searchQuery) ? null : QItem.item.itemNm.like("%" + searchQuery + "%");
    }
    @Override
    public Page<MainItemDto> getMainItemPage(ItemSearchDto itemSearchDto, Pageable pageable) {
        QItem item = QItem.item;
        QItemImg itemImg = QItemImg.itemImg;

        QueryResults<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())
                .fetchResults();

        List<MainItemDto> content = results.getResults();
        long total = results.getTotal();
        return new PageImpl<>(content, pageable, total);
    }

 

 

 

com.shop.service.ItemService.java

// ItemService.java

... 기존 임포트 생략 ...

import com.shop.dto.MainItemDto;

public class ItemService {

... 생략 ...

    @Transactional(readOnly = true)
    public Page<MainItemDto> getMainItemPage(ItemSearchDto itemSearchDto, Pageable pageable){
        return itemRepository.getMainItemPage(itemSearchDto, pageable);
    }
}

 

 

com.shop.controller.MainController.java

// MainController.java

package com.shop.controller;

import com.shop.dto.ItemSearchDto;
import com.shop.dto.MainItemDto;
import com.shop.service.ItemService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Optional;

@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, 6);
        Page<MainItemDto> items = itemService.getMainItemPage(itemSearchDto, pageable);
        model.addAttribute("items", items);
        model.addAttribute("itemSearchDto", itemSearchDto);
        model.addAttribute("maxPage", 5);
        return "main";
    }
}

 

 

 

main.html

https://rogi221.tistory.com/178

 

ItemForm.html - github

https://rogi221.tistory.com/177 깃허브에서 자료 복사해서 입력 // ItemFrom.html 상품 등록 판매중 품절 상품명 Incorrect data 가격 Incorrect data 재고 Incorrect data 상품 상세 내용 Incorrect data 저장 수정

rogi221.tistory.com

 


 

 

 

 

상품 상세 페이지

 

  • 메인 페이지에서 상품 이미지나 상품 정보를 클릭 시 상품의 상세 정보를 보여주는 페이지 구현

 

com.shop.controller.ItemController.java

// ItemController.java

... 생략 ...

    @GetMapping(value = "/item/{itemId}")
    public String itemDtl(Model model, @PathVariable("itemId") Long itemId) {
        ItemFormDto itemFormDto = itemService.getItemDtl(itemId);
        model.addAttribute("item", itemFormDto);
        return "item/itemDtl";
    }
}

 

 

resources/templates/item/itmeDtl.html

https://rogi221.tistory.com/178

 

ItemForm.html - github

https://rogi221.tistory.com/177 깃허브에서 자료 복사해서 입력 // ItemFrom.html 상품 등록 판매중 품절 상품명 Incorrect data 가격 Incorrect data 재고 Incorrect data 상품 상세 내용 Incorrect data 저장 수정

rogi221.tistory.com


 

728x90
반응형