상품 수정
등록이나 조회는 간단했지만 수정은 다르다. JPA에서는 수정하는 방법이 변경감지와 병합(merge) 두가지가 있다.
먼저 상품 수정을 해보자.
수정의 경로는 items/상품 id/edit이다.
ItemController에 해당 경로를 다룰 메서드를 추가해준다. 이때 id를 통해 경로를 매핑할때는 아래서 보듯이 {}문법과 @PathVariable애너테이션을 통해 매핑해준다.
@GetMapping("items/{itemId}/edit")
public String updateItemForm(@PathVariable("itemsId") Long itemId, Model model){
Book item = (Book) itemService.findOne(itemId); //Book타입 엔티티 반환
BookForm form = new BookForm();
form.setId(item.getId()); //업데이트는 form을 통해서 이뤄진다.
form.setName(item.getName());
form.setPrice(item.getPrice());
form.setStockQuantity(item.getStockQuantity());
form.setAuthor(item.getAuthor());
form.setIsbn(item.getIsbn());
model.addAttribute("form", form);
return "items/updateItemForm";
}
다음으로 뷰를 만들어주자.
<!DOCTYPE HTML>
<html xmlns:th="<http://www.thymeleaf.org>">
<head th:replace="fragments/header :: header" />
<body>
<div class="container">
<div th:replace="fragments/bodyHeader :: bodyHeader"/>
<form th:object="${form}" method="post">
<!-- id -->
<input type="hidden" th:field="*{id}" />
<div class="form-group">
<label th:for="name">상품명</label>
<input type="text" th:field="*{name}" class="form-control"
placeholder="이름을 입력하세요" />
</div>
<div class="form-group">
<label th:for="price">가격</label>
<input type="number" th:field="*{price}" class="form-control"
placeholder="가격을 입력하세요" />
</div>
<div class="form-group">
<label th:for="stockQuantity">수량</label>
<input type="number" th:field="*{stockQuantity}" class="formcontrol" placeholder="수량을 입력하세요" />
</div>
<div class="form-group">
<label th:for="author">저자</label>
<input type="text" th:field="*{author}" class="form-control"
placeholder="저자를 입력하세요" />
</div>
<div class="form-group">
<label th:for="isbn">ISBN</label>
<input type="text" th:field="*{isbn}" class="form-control"
placeholder="ISBN을 입력하세요" />
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<div th:replace="fragments/footer :: footer" />
</div> <!-- /container -->
</body>
</html>
이제 수정 뷰단이 나온다. 서브밋을 눌렀을때 post를 받을 컨트롤러내 메서드를 아직 구성하지 않았으므로 현재로썬 submit을 눌러도 아무일도 일어나지 않는다.
post메서드를 만들어주자,.
@PostMapping("items/{itemId}/edit")
public String updateItem(@PathVariable String itemId, @ModelAttribute("form") BookForm form){
Book book = new Book();
book.setId(form.getId()); //업데이트는 form을 통해서 이뤄진다.
book.setName(form.getName());
book.setPrice(form.getPrice());
book.setStockQuantity(form.getStockQuantity());
book.setAuthor(form.getAuthor());
book.setIsbn(form.getIsbn());
itemService.saveItem(book); //merge()
return "redirect:/items"; //상품 목록으로 리다이렉
}
post로 넘어온 form의 필드값들을 엔티티 book에다가 넘겨주고, 해당 book을 영속화해줘야 한다.