이번 시간에는 상품 수정에 관련된 부분과 변경감지와 병합에 대해 다뤄보겠다.
// 상품 수정
// itemId는 변경될 수 있으므로 @PathVariable 사용
@GetMapping("items/{itemId}/edit")
public String updateItemForm(@PathVariable("itemId") Long itemId, Model model) {
// 캐스팅을 하는 것이 좋은 방법은 아니나, 여기서는 예제 단순화를 위해 사용
Food item = (Food) itemService.findOne(itemId);
// 폼을 업데이트 할 건데, 엔티티가 아닌 BookForm 을 보냄
FoodForm form = new FoodForm();
form.setId(item.getId());
form.setName(item.getName());
form.setPrice(item.getPrice());
form.setStockQuantity(item.getStockQuantity());
form.setAllowance(item.getAllowance());
form.setIngredient(item.getIngredient());
model.addAttribute("form", form);
return "items/updateItemForm";
}
@PostMapping("items/{itemId}/edit")
// @PathVariable Long itemId : 폼에서 그대로 넘어오기 때문에 생략해도 됨
// @ModelAttribute("form") : 폼에서 오브젝트 이름으로 설정한 부분이 그대로 넘어옴
public String updateItem(@PathVariable Long itemId, @ModelAttribute("form") FoodForm form) {
itemService.updateItem(itemId, form.getName(), form.getPrice(), form.getStockQuantity());
return "redirect:/items";
}
<!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="form-control" placeholder="수량을 입력하세요" />
</div>
<div class="form-group">
<label th:for="allowance">권장량</label>
<input type="text" th:field="*{allowance}" class="form-control" placeholder="하루 권장량을 입력하세요" />
</div>
<div class="form-group">
<label th:for="ingredient">주재료</label>
<input type="text" th:field="*{ingredient}" class="form-control" placeholder="들어가는 주재료를 입력하세요" />
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<div th:replace="fragments/footer :: footer" />
</div> <!-- /container -->
</body>
</html>
/items/{itemId}/edit
URL을 GET
방식으로 요청updateItemForm()
메서드를 실행하는데 이 메서드는 itemService.findOne(itemId)
를items/updateItemForm
)에 전달변경 감지와 병합은 정말 중요한 내용으로, 이전에 따로 포스팅 한 적이 있으므로 이번 시간에는 핵심만 간단히 짚고 넘어가겠다!
준영속 엔티티란🤔?
➡️ 영속성 컨텍스트가 더는 관리하지 않는 엔티티를 말한다.
준영속 엔티티를 수정하는 2가지 방법
1. 변경 감지 기능 사용
Dirty Checking
) 이 동작해서 데이터베이스에 UPDATE SQL 실행merge
) 사용merge()
를 실행한다.id
)와 변경할 데이터를 명확하게 전달 (파라미터 or dto) 📌 권장 코드
@PostMapping(value = "/items/{itemId}/edit")
public String updateItem(@ModelAttribute("form") BookForm form) {
itemService.updateItem(form.getId(), form.getName(), form.getPrice());
return "redirect:/items";