inblog logo
|
jay0628
    SpringBoot

    [Spring Boot] 15. 스프링부트 상점 v1 (6) StoreController 관련 기능 완성하기

    김주희's avatar
    김주희
    Mar 19, 2025
    [Spring Boot] 15. 스프링부트 상점 v1 (6) StoreController 관련 기능 완성하기
    Contents
    1. 상품등록 만들기2. 상품목록 만들기3. 상품상세보기 만들기4. 상품 삭제하기 만들기5. 상품수정 만들기

    1. 상품등록 만들기

    0. 화면부터 보자!

    notion image

    1. store/save-form.mustache로 가자!

    1. input 태그의 name 속성의 값은 db 상의 컬럼명과 일치하는 게 아니라 모델링한 것과 일치해야하므로 Store.java를 확인해야 한다.
      1. save-form.mustache
        notion image
        Store.java
        notion image
     

    2. 이제 StoreContoller로 가자!

    1. controller에서 값 잘 받고 응답 받는거 확인한다.
      1. Cursor에서는 매개변수에 @RequestParam("") 붙여주기
    1. controller의 책임은 끝났으니까 service로 넘긴다.
    1. 의존성 주입!
    notion image
    @PostMapping("/store/save") public String save(@RequestParam("name")String name, @RequestParam("stock")int stock, @RequestParam("price")int price) { storeService.상품등록(name,stock,price); return "redirect:/"; }
     

    3. StoreService로 가자!

    1. 상품등록은 write(insert)이고 write는 commit이 적용되어야 하니까 @Transactional 붙여주기
    1. service의 책임은 끝났으니까 repository로 넘긴다.
    1. 의존성 주입!
    notion image
    @Transactional // import 주의 jakarta 아님! public void 상품등록(String name, int stock, int price){ storeRepository.save(name, stock, price); }
     

    4. StoreRepository로 가자!

    1. db로부터 return 받는게 없으니까 오브젝트 매핑 없어도 된다!
    1. 의존성 주입!
    notion image
    public void save(String name, int stock, int price){ Query query = em.createNativeQuery("insert into store_tb(name, stock, price) values(?,?,?)"); query.setParameter(1, name); query.setParameter(2, stock); query.setParameter(3, price); query.executeUpdate(); }
     

    5. Repository → Service → Controller

    1. respository에서 return하는게 없으므로 service에서도 받는게 없다.
    1. service에서도 return하는게 없으므로 controller에서도 받는게 없다.
     

    2. 상품목록 만들기

    0. 화면부터 보자!

    notion image
     

    1. StoreContoller로 가자!

    1. 일단 controller의 책임은 끝났으니까 service로 넘긴다.
    @GetMapping("/") public String list() { storeService.상품목록(); return "store/list"; }
     

    2. StoreService로 가자!

    1. 일단 service의 책임은 끝났으니까 repository로 넘긴다.
    public void 상품목록(){ storeRepository.findAll(); }
     

    3. StoreRepository로 가자!

    1. select문을 통해 db로부터 리턴 받으므로 오브젝트 매핑을 위해 Store.class를 추가해준다.
    1. select * ⇒ 여러 개의 행을 리턴하므로 getResultList()
    1. Store 객체들을 list로 리턴하니까 리턴 타입은 List<Store>가 된다.
    1. 여기서 움직이는 데이터는 List<Store>이므로 List<Store>가 model이 된다.
    // model = List<Store> public List<Store> findAll() { // 조건 : 오브젝트 매핑은 @Entity가 붙어있어야지만 가능하다. (디폴트 생성자를 호출) // reflection을 통한 setter 호출 Query query = em.createNativeQuery("select * from store_tb order by id desc", Store.class); return query.getResultList(); }
     

    4. 다시 StoreService로 돌아오자!

    1. storeRepository.findAll()의 리턴 타입이 List<Store>이므로 List<Store> storeList로 받는다.
    1. Repository로부터 받은 List<Store>를 다시 Controller로 리턴해줘야 하므로 메서드의 리턴 타입은 List<Store>로 수정하고 storeList를 리턴한다.
    1. 여기서 움직이는 데이터는 List<Store>이므로 List<Store>가 model이 된다.
    // model = List<Store> (움직이는 데이터) public List<Store> 상품목록(){ List<Store> storeList = storeRepository.findAll(); return storeList; }
     

    5. 다시 StoreController로 돌아오자!

    1. storeService.상품목록()로부터 List<Store> storeList를 받는다.
    1. 리턴 받은 Object를 request에 담아서 View인 store/list.mustache로 보내줘야 한다.
      1. request.setAttribute(”key”,value)
    // 동적 페이지 @GetMapping("/") public String list(HttpServletRequest request) { // MVC List<Store> storeList = storeService.상품목록(); request.setAttribute("models", storeList); // Object = List의 Store 타입 return "store/list"; }
     

    6. store/list.mustache로 가자!

    1. List<Store> storeList인 models를 돌면서 id와 name을 받아올 수 있도록 조건문을 사용하자
    notion image
     

    3. 상품상세보기 만들기

    0. 화면부터 보자!

    notion image
     

    1. StoreContoller로 가자!

    1. 일단 controller의 책임은 끝났으니까 service로 넘긴다.
      1. 특정 id의 상품에 대해서 상세보기 하는 것이므로 id를 service로 넘겨야 한다.
    @GetMapping("/store/{id}") public String detail(@PathVariable("id") int id) { storeService.상품상세보기(id) return "store/detail"; }
     

    2. StoreService로 가자!

    1. 일단 service의 책임은 끝났으니까 repository로 넘긴다.
      1. id를 repository에도 넘긴다
    public void 상품상세보기(int id) { storeRepository.findById(id); }
     

    3. StoreRepository로 가자!

    1. select문을 통해 db로부터 리턴 받으므로 오브젝트 매핑을 위해 Store.class를 추가해준다.
    1. where id = ?을 통해 1개의 행을 리턴하므로 getSingleResult()
    1. getSingleResult()는 리턴 타입이 Object이므로 다운캐스팅이 필요하다!
    1. Store 객체를 하나만 리턴하니까 리턴 타입은 Store가 된다.
    public Store findById(int id){ Query query = em.createNativeQuery("select * from store_tb where id = ?" , Store.class); query.setParameter(1, id); return (Store) query.getSingleResult(); }
     

    4. 다시 StoreService로 돌아오자!

    1. storeRepository.findById의 리턴 타입이 Store 이므로 Store store로 받는다.
    1. Repository로부터 받은Store 를 다시 Controller로 리턴해줘야 하므로 메서드의 리턴 타입은 Store 로 수정하고 store를 리턴한다.
    public Store 상품상세보기(int id) { Store store = storeRepository.findById(id); return store; }
     

    5. 다시 StoreController로 돌아오자!

    1. storeService.상품상세보기(id)로부터 Store store를 받는다.
    1. 리턴 받은 Object를 request에 담아서 View인 store/detail.mustache로 보내줘야 한다.
      1. request.setAttribute(”key”,value)
      2. 상품목록에서 설정한 key는 리스트이므로 models로 했고 여기서는 한 개만 담아서 보내기 때문에 model로 하자
    @GetMapping("/store/{id}") public String detail(@PathVariable("id") int id, HttpServletRequest request) { Store store = storeService.상품상세보기(id); request.setAttribute("model", store); return "store/detail"; }
     

    6. store/detail.mustache로 가자!

    1. 템플릿 엔진 mustache의 데이터 전달 문법과, key값인 model에 맞춰서 detail.mustache를 수정한다.
    notion image
     

    4. 상품 삭제하기 만들기

    0. 화면부터 보자!

    notion image
     

    1. store/detail.mustache로 가자!

    1. 확인하고 controller로~
    notion image
     

    2. StoreContoller로 가자!

    1. controller의 책임은 끝났으니까 service로 넘긴다.
      1. 특정 id의 상품에 대해서 삭제하는 것이므로 id를 service로 넘겨야 한다.
    @PostMapping("/store/{id}/delete") public String delete(@PathVariable("id") int id) { storeService.상품삭제(id); return "redirect:/"; }
     

    3. StoreService로 가자!

    1. 삭제를 할 때에는 상품이 있는지 먼저 확인하고 (1) 있을 경우 삭제하도록(2) 비지니스 로직을 구성한다.
    1. 상품삭제는 write(delete)이고 write는 commit이 적용되어야 하니까 @Transactional 붙여주기
    1. service의 책임은 끝났으니까 repository로 넘긴다.
      1. id도 repository로 넘긴다.
    @Transactional // insert, delete, update시에 사용 : 함수 종료시 commit됨 public void 상품삭제(int id) { // 1. 상품 있는지 확인하고 Store store = storeRepository.findById(id); // 2. 삭제하기 if (store == null) { throw new RuntimeException("상품이 없는데 왜 삭제를 ㅠㅠ"); } storeRepository.deleteById(id); }
     

    4. StoreRepository로 가자!

    1. db로부터 return 받는게 없으니까 오브젝트 매핑 없어도 된다!
    public void deleteById(int id){ Query query = em.createNativeQuery("delete from store_tb where id = ?"); query.setParameter(1, id); query.executeUpdate(); }

    5. Repository → Service → Controller

    1. respository에서 deleteById()에 대해서 return하는게 없으므로 service에서도 받는게 없다.
    1. service에서도 return하는게 없으므로 controller에서도 받는게 없다.
     

    5. 상품수정 만들기

    1. 일단 화면에 값을 뿌려야 한다!
    notion image
     

    1. update-form.mustache부터 가서 보자!

    1. value 속성 설정을 통해 값을 미리 입력해둔 상태기 때문에 상품상세보기를 참고해서 id에 대한 상품 정보를 가져와야 한다.
    1. 일단 화면에 값을 뿌려야 한다!
    notion image
     
     

    Controller

    @GetMapping("/store/{id}/update-form") public String updateForm(@PathVariable("id") int id, HttpServletRequest request) { Store store = storeService.상품상세보기(id); request.setAttribute("model", store); return "store/update-form"; }
     
    notion image
     
     
     
     
     
     
     
    여기는 수정하기 버튼에 대해서 만든거

    2. 이제 StoreContoller로 가자!

    1. controller에서 값 잘 받고 응답 받는거 확인한다.
      1. Cursor에서는 매개변수에 @RequestParam("") 붙여주기
      2. sout으로 확인해보기
      3. notion image
     
      @PostMapping("/store/{id}/update") public String update(@PathVariable("id") int id, @RequestParam("name")String name, @RequestParam("stock")int stock, @RequestParam("price")int price) { storeService.상품수정(id, name, stock, price); return "redirect:/store/" + id; }
       
       

      Service

      1. write니까 @Transaction을 먼저 걸자!
      @Transactional public void 상품수정(int id, String name, int stock, int price) { // 1. 상품 있는지 확인하고 Store store = storeRepository.findById(id); // 2. 수정하기 if (store == null){ throw new RuntimeException("상품이 없는데 왜 수정을 ㅠㅠ"); } storeRepository.updateById(id, name, stock, price); }
       

      Repository

      public void updateById(int id, String name, int stock, int price) { Query query = em.createNativeQuery("update store_tb set name = ?, stock = ?, price = ? where id = ?"); query.setParameter(1, name); query.setParameter(2, stock); query.setParameter(3, price); query.setParameter(4, id); query.executeUpdate(); }
       
       
      Share article

      jay0628

      RSS·Powered by Inblog