이 내용은 스프링 부트 쇼핑몰 프로젝트 with JPA 책을 학습한 내용입니다.
1. 상품 조회
- 상품을 수정하려면 해당 상품을 불러와야 함
- 따라서, ItemService 에 상품 조회 메소드 추가 (조회 기능이므로 읽기 전용으로 불러옴)
- item 엔티티와 img 정보 엔티티를 itemFormDto 객체로 변환 후 반환하는 조회 기능
// 아이템 수정
public ItemFormDto getItemDetail(Long itemId) {
List<ItemImg> itemImgList = itemImgRepository.findByItemIdOrderByIdAsc(itemId);
List<ItemImgDto> itemImgDtoList = new ArrayList<>();
for (ItemImg itemImg : itemImgList) {
ItemImgDto itemImgDto = ItemImgDto.of(itemImg); // 엔티티를 dto로 변환
itemImgDtoList.add(itemImgDto); // dto를 추가해서 리스트 생성(웹사이트에 들고가기 위해서)
}
Item item = itemRepository.findById(itemId).orElseThrow(EntityNotFoundException::new);
ItemFormDto itemFormDto = ItemFormDto.of(item);
itemFormDto.setItemImgDtoList(itemImgDtoList);
return itemFormDto;
}
2. 상품 수정 페이지 Controller
- 상품 등록 페이지를 동일하게 사용 ("저장" 버튼을 "수정" 버튼으로 출력)
- 수정 대상 상품의 Id 값을 포함한 Get URL 요청으로 상품 수정 페이지를 요청
- 해당 상품을 조회한 뒤 itemFormDto 객체를 기반으로 상품 수정 페이지 생성 및 반환
@GetMapping("/admin/item/{itemId}")
public String itemDetail(@PathVariable("itemId")Long itemId, Model model) {
try {
ItemFormDto itemFormDto = itemService.getItemDetail(itemId);
model.addAttribute("itemFormDto", itemFormDto); // itemForm.html에서 itemFormDto로 받기 때문에
} catch (EntityNotFoundException E) {
model.addAttribute("errorMessage", "존재하지 않는 상품입니다.");
model.addAttribute("itemFormDto", new ItemFormDto());
return "item/itemForm";
}
return "item/itemForm";
}
- 상품 수정 페이지
- /admin/item/{상품 id}
3. ItemImgService 수정
- 상품 이미지를 수정한 경우, 기존의 이미지 정보 객체를 불러옴 (조회)
- 기존 이미지 파일이 존재한다면 삭제 (존재하지 않는다면 이미지를 추가한 것)
- 수정한 이미지 파일을 fileService.uploadFile() 메소드를 통해 업로드
- itemImgRepository.save() 가 아닌 savedItemImg.updateItemImg() 메소드로 객체를 수정
// 이미지 수정
public void updateItemImg(Long ItemImgId, MultipartFile itemImgFile) throws IOException {
// itemImgFile이 빈게 아니면
if(!itemImgFile.isEmpty()) {
ItemImg itemImg = itemImgRepository.findById(ItemImgId).orElseThrow(EntityNotFoundException::new);
// 이미지 파일이 존재하는 경우
if(!StringUtils.isEmpty(itemImg.getImgName())) {
fileService.deleteFile(itemImgLocation + "/" + itemImg.getImgName());
}
String oriName = itemImgFile.getOriginalFilename();
String imgName = fileService.uploadFile(itemImgLocation, oriName, itemImgFile.getBytes());
String imgUrl = "/images/item/" + imgName;
itemImg.updateItemImg(oriName, imgName, imgUrl);
}
}
• 상품 수정 페이지에서 기존 이미지 파일을 수정하지 않았다면 "null" 객체로 넘어옴 (상품 이미지 라벨에는 이름이 표시되어 있지만 파일이 등록된 것은 아님)
4. 상품 업데이트 로직
- Item Entity 클래스에 업데이트 로직 생성
- 엔티티 클래스에 로직을 추가한다면 좀 더 객체지향적이고 코드 재활용이 가능, 또한 변경 포인트를 한군데에서 관리할 수 있음
public void updateItem(ItemFormDto itemFormDto) {
this.itemNm = itemFormDto.getItemNm();
this.price = itemFormDto.getPrice();
this.stockNumber = itemFormDto.getStockNumber();
this.itemDetail = itemFormDto.getItemDetail();
this.itemSellStatus = ItemSellStatus.valueOf(itemFormDto.getItemSellStatus());
}
5. ItemService 수정
- 상품 Id 를 이용하여 기존의 상품 Entity 객체를 불러온 뒤, Post 입력값으로 들어온 상품 정보로 수정
- itemImgService.updateItemImg() 메소드를 이용하여 상품 이미지 수정
public Long updateItem(ItemFormDto itemFormDto, List<MultipartFile> itemImgFileList) throws IOException {
// 상품 수정
Item item = itemRepository.findById(itemFormDto.getId()).orElseThrow(EntityNotFoundException::new);
item.updateItem(itemFormDto);
List<Long> itemImgIds = itemFormDto.getItemImgIds();
// 이미지 수정
for (int i = 0; i < itemImgFileList.size(); i++) {
itemImgService.updateItemImg(itemImgIds.get(i), itemImgFileList.get(i));
}
// 수정 후 어떤 아이템인지 아이템의 아이디를 알려줌
return item.getId();
}
6. 상품 수정 Controller
- 상품 등록 Controller와 거의 동일 (itemService. saveItem -> updateItem)
// 아이템 수정 후 할 일
@PostMapping("/admin/item/{itemId}")
public String itemUpdate(@Valid ItemFormDto itemFormDto, BindingResult bindingResult
, Model model, @RequestParam("itemImgFile") List<MultipartFile> itemImgFileList) {
if(bindingResult.hasErrors()) {
return "item/itemForm";
}
if(itemImgFileList.get(0).isEmpty() && itemFormDto.getId() == null) {
model.addAttribute("errorMessage", "첫 번째 상품 이미지는 필수입니다.");
return "item/itemForm";
}
try {
itemService.updateItem(itemFormDto, itemImgFileList);
} catch (IOException e) {
model.addAttribute("errorMessage", "상품 수정 중에 오류가 발생했습니다.");
return "item/itemForm";
}
// 홈으로 리턴
return "redirect:/";
}
7. 상품 등록 동작 과정
- 상품 등록은 save() 메소드만을 수행
- 상품 수정은 조회 -> update() 메소드를 수행 (변경 감지 이용)
① "ADMIN" 권한을 가진 아이디로 상품 수정 페이지 Get 요청 ("/admin/item/{itemId}")
② Item Controller 에서 itemService.getItemDtl(itemId) 수행하여 해당 상품 조회
③ Item Controller 에서 상품 수정 페이지 반환하면서 해당 상품 Dto 객체 넘김
④ 상품 수정 페이지에서 수정한 후 "수정" (POST 요청)
⑤ Item Controller 에서 입력값을 검증하고 itemService.updateItem() 메소드를 수행
- 이 때, 파라미터는 입력받은 itemFormDto 객체와 이미지 정보를 담고있는 itemImgFileList 를 넘김
⑥ itemService 에서 Item 객체를 조회하여 불러온 뒤 item.updateItem(itemFormDto) 수행
⑦ itemService 에서 itemImgService.updateItemImg() 메소드 수행
- 이 때, 파라미터는 "상품 이미지의 id", "상품 이미지 파일"
⑧ itemImgService 에서 기존 이미지 파일 삭제 후 savedItemImg.updateItemImg () 수행
'Web & Android > 스프링 부트 쇼핑몰 프로젝트 with JPA' 카테고리의 다른 글
[스프링 부트 쇼핑몰 프로젝트 with JPA] 8-2. [상품 관리] 상품 목록 페이지 (0) | 2023.10.16 |
---|---|
[스프링 부트 쇼핑몰 프로젝트 with JPA] 8-1. [상품 관리] 상품 목록 조회 Querydsl (0) | 2023.10.16 |
[스프링 부트 쇼핑몰 프로젝트 with JPA] 6-2. [상품 등록] Controller, Service, Repository (0) | 2023.10.15 |
[스프링 부트 쇼핑몰 프로젝트 with JPA] 6-1. [상품 등록] Entity, DTO, View (0) | 2023.10.15 |
[스프링 부트 쇼핑몰 프로젝트 with JPA] 5. Entity 공통 속성 공통화(Auditing) (0) | 2023.10.15 |