스프링 부트와 JPA 활용1 - 웹 계층 개발 6

JOY·2022년 5월 13일
0
post-thumbnail

📌 스프링 부트와 JPA 활용1 - 웹 계층 개발 6

인프런 - 스프링 부트와 JPA 활용1 by 김영한 을 기반으로 작성된 글입니다.
실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발


웹 계층 개발 목차

1. 홈 화면과 레이아웃

2. 회원 등록

3. 회원 목록 조회

4. 상품 등록

5. 상품 목록

6. 상품 수정

7. 변경 감지와 병합(merge)

8. 상품 주문

9. 주문 목록 검색, 취소


구현 기능

  • 홈 화면
  • 회원 기능
    • 회원 등록
    • 회원 조회
  • 상품 기능
    • 상품 등록
    • 상품 수정
    • 상품 조회
  • 주문 기능
    • 상품 주문
    • 주문내역 조회
    • 주문 취소

상품 수정 컨트롤러(ItemController.java)

코드 추가

@Controller
@RequiredArgsConstructor
public class ItemController {
	/**
     * 상품 수정 폼
     */
    @GetMapping(value = "/items/{itemId}/edit")
    public String updateItemForm(@PathVariable("itemId") Long itemId, Model model) {
		//item은 Book 만 가져온다고 가정
        Book item = (Book) itemService.findOne(itemId);
        
        //form을 update 할 때 Book 엔티티가 아니라 BookForm을 보낼 것
        BookForm form = new BookForm();
        form.setId(item.getId());
        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";
    }

    /**
     * 상품 수정
     */
    @PostMapping(value = "/items/{itemId}/edit")
    public String updateItem(@PathVariable String itemId, @ModelAttribute("form") BookForm form) {

        Book book = new Book();

        book.setId(form.getId());
        book.setName(form.getName());
        book.setPrice(form.getPrice());
        book.setStockQuantity(form.getStockQuantity());
        book.setAuthor(form.getAuthor());
        book.setIsbn(form.getIsbn());

        itemService.saveItem(book);
        return "redirect:/items";
    }
}

📍 설명

  • @PathVariable : URL 변수
    Controller는 URL에서 { } 에 parameter를 넣는 URI 템플릿을 사용할 수 있고
    Controller method parameter에는 해당 어노테이션(@PathVariable)을 이용
    URL에 {}로 들어가는 변수(path Variable)를 파라미터로 지정할 수 있다

    http: //localhost:8080/items/1/edit
    위의 URL에서 볼드체 부분을 처리해준다

    @GetMapping(value = "/items/{itemId}/edit") 에서 사용한
    {itemId} 의 변수명을 @PathVariable("itemId") 의 변수명으로 사용한다

	@GetMapping(value = "/items/{itemId}/edit")
    public String updateItemForm(@PathVariable("itemId") Long itemId, Model model) {}
  • updateItem()
    @ModelAttribute("form") 은 뷰(items/updateItemForm)에서
    th:object="${form}"form 이 넘어 온다

  1. book 엔티티 넘김
itemService.saveItem(book);
return "redirect:/items"; 호출
       
  1. itemRepository - save() 호출
public class ItemService {
@Transactional
    public void saveItem(Item item){
        itemRepository.save(item);
    }
}
  1. null 이면 새로운 object니까 persist
    null 이 아니면 DB에서 수정할 목적으로 호출한 것
public class ItemRepository {
  public void save(Item item){
          //em.persist - 신규 등록
          if (item.getId() == null){
              em.persist(item);
          } else{
              // update
              em.merge(item);
          }
      }
}

변경 감지와 병합(merge) 에 대한 부분은 다음 게시물에 포스팅 하겠다.

상품 수정 (updateItemForm.html)

코드는 일부만 나타내도록 하겠다

<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>

📍 설명

  • 상품 수정 폼 이동

    1. 수정 버튼을 선택하면 /items/{itemId}/edit URL을 GET 방식으로 요청
    2. updateItemForm() 메서드 실행,
      해당 메서드는 itemService.findOne(itemId) 를 호출하여 수정할 상품 조회
    3. 조회 결과를 Model 객체에 담아 뷰(items/updateItemForm)에 전달
  • 상품 수정 실행
    상품 수정 폼(HTML) - 상품의 id(hidden), 상품명, 가격, 수량, 저자, ISBN

    1. 상품 수정 폼에서 정보 수정 후 submit
    2. /items/{itemId}/edit URL을 POST 방식으로 요청
    3. updateItem() 메서드 실행,
      이때 컨트롤러에 파라미터로 덤어온 item 엔티티 인스턴스는 현재 준영속 상태
      따라서, 영속성 컨텍스트의 지원을 받을 수 없고 수정해도 변경 감지 기능은 동작하지 않음

💡 form 태그에 action 속성이 없다? - 현재 URL을 그대로 사용

: action 속성은 데이터를 서버로 보낼 때 데이터를 받을 URL을 지정한다

  • 좋은 URL 설계 방식
    같은 URL인데,
    수정 화면을 노출할 때 - GET 사용
    수정 화면의 데이터를 실제 변경할 때 - POST 사용

📍 실행 결과

  1. 상품 등록
상품 등록상품 목록 - 상품 등록 확인
  1. 상품 수정(가격, 수량, ISBN) - 상품명 JPA
상품 수정상품 목록 - 상품 수정 확인
profile
Just Do IT ------- 🏃‍♀️

0개의 댓글