[Spring Boot] 6. Spring Boot Project (Store v1) in Curser_3.Store

김미숙's avatar
Mar 27, 2025
[Spring Boot] 6. Spring Boot Project (Store v1) in Curser_3.Store
‼️
  • @RequiredArgsConstructor
    • final 붙은 필드로만 생성자 만든다
    • @RequiredArgsConstructor @Controller // IoC (제어의역전) -> HashSet public class StoreController { private final StoreService storeService;

1. 상품등록

save-form

‼️
  • value는 기본값
    • 잘 만들어졌는지 확인할 때 입력하지 않아도 입력값이 들어가 있게
    • 다 확인되고 나면 지우면 됨
{{>layout/header}} <section> <form action="/store/save" method="post"> <input type="text" placeholder="상품명" name="name" value="바나나"><br> <input type="text" placeholder="수량" name="stock" value="50"><br> <input type="text" placeholder="가격" name="price" value="3000"><br> <button type="submit">상품등록</button> </form> </section> </body> </html>

StoreRepository

package com.metacoding.storev1.store; import org.springframework.stereotype.Repository; import jakarta.persistence.EntityManager; import jakarta.persistence.Query; @Repository public class StoreRepository { private final EntityManager em; public StoreRepository(EntityManager em) { this.em = em; } 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(); } }

StoreController

package com.metacoding.storev1.store; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller // IoC (제어의역전) -> HashSet public class StoreController { private StoreService storeService; public StoreController(StoreService storeService) { this.storeService = storeService; } @GetMapping("/") public String list() { return "store/list"; } @GetMapping("/store/save-form") public String saveForm() { return "store/save-form"; } @GetMapping("/store/{id}") public String detail(@PathVariable("id") int id) { return "store/detail"; } @GetMapping("/store/{id}/update-form") public String updateForm(@PathVariable("id") int id) { return "store/update-form"; } @PostMapping("/store/{id}/delete") public String delete(@PathVariable("id") int id) { return "redirect:/"; } @PostMapping("/store/save") public String save(@RequestParam("name") String name, @RequestParam("stock") int stock, @RequestParam("price") int price) { System.out.println("name" + name); System.out.println("stock" + stock); System.out.println("price" + price); storeService.상품등록(name, stock, price); return "redirect:/"; } @PostMapping("/store/{id}/update") public String update(@PathVariable("id") int id) { return "redirect:/store/1"; } }

StoreService

package com.metacoding.storev1.store; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class StoreService { private StoreRepository storeRepository; public StoreService(StoreRepository storeRepository) { this.storeRepository = storeRepository; } @Transactional public void 상품등록(String name, int stock, int price) { storeRepository.save(name, stock, price); } }

➡ localhost:8080/store/save-form

notion image

상품등록 버튼을 누르면 redirection 되서 상품목록 page 로 이동

notion image
 

2. 상품 목록

store/list

{{>layout/header}} <section> <table border="1"> <tr> <th>번호</th> <th>상품명</th> <th></th> </tr> {{#models}} <tr> <td>{{id}}</td> <td>{{name}}</td> <td><a href ="store/{{id}}">상세보기</a></td> </tr> {{/models}} </table> </section> </body> </html>

StoreRepository

package com.metacoding.storev1.store; import java.util.List; import org.springframework.stereotype.Repository; import jakarta.persistence.EntityManager; import jakarta.persistence.Query; @Repository public class StoreRepository { private final EntityManager em; public StoreRepository(EntityManager em) { this.em = em; } 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(); } public List<Store> findAll() { // 조건: 오브젝트 매핑은 @Entity 가 붙어야지만 가능하다 (디폴트 생성자를 호출) Query query = em.createNativeQuery("select * from store_tb order by id desc", Store.class); return query.getResultList(); } }

StoreController

package com.metacoding.storev1.store; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import jakarta.servlet.http.HttpServletRequest; @Controller // IoC (제어의역전) -> HashSet public class StoreController { private StoreService storeService; public StoreController(StoreService storeService) { this.storeService = storeService; } @GetMapping("/") public String list(HttpServletRequest request) { // MVC List<Store> storeList = storeService.상품목록(); request.setAttribute("models", storeList); return "store/list"; } @GetMapping("/store/save-form") public String saveForm() { return "store/save-form"; } @GetMapping("/store/{id}") public String detail(@PathVariable("id") int id) { return "store/detail"; } @GetMapping("/store/{id}/update-form") public String updateForm(@PathVariable("id") int id) { return "store/update-form"; } @PostMapping("/store/{id}/delete") public String delete(@PathVariable("id") int id) { return "redirect:/"; } @PostMapping("/store/save") public String save(@RequestParam("name") String name, @RequestParam("stock") int stock, @RequestParam("price") int price) { System.out.println("name" + name); System.out.println("stock" + stock); System.out.println("price" + price); storeService.상품등록(name, stock, price); return "redirect:/"; } @PostMapping("/store/{id}/update") public String update(@PathVariable("id") int id) { return "redirect:/store/1"; } }

StoreService

package com.metacoding.storev1.store; import java.util.List; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class StoreService { private StoreRepository storeRepository; public StoreService(StoreRepository storeRepository) { this.storeRepository = storeRepository; } @Transactional public void 상품등록(String name, int stock, int price) { storeRepository.save(name, stock, price); } public List<Store> 상품목록() { List<Store> storeList = storeRepository.findAll(); return storeList; }
 
notion image
notion image
 

3. 상세보기

detail

{{>layout/header}} <section> <a href="/store/{{model.id}}/update-form">수정화면가기</a> <form action="/store/{{model.id}}/delete" method="post"> <button type="submit">삭제</button> </form> <div> 번호 : {{model.id}} <br> 상품명 : {{model.name}} <br> 상품가격 : {{model.price}}원 <br> 상품재고 : {{model.stock}}개 <br> </div> <form action="#"> <input type="hidden" value="{{model.id}}"> <input type="text" placeholder="당신은 누구인가요?"> <input type="text" placeholder="Enter 개수"> <button type="submit">구매</button> </form> </section> </body> </html>

StoreRepository

package com.metacoding.storev1.store; import java.util.List; import org.springframework.stereotype.Repository; import jakarta.persistence.EntityManager; import jakarta.persistence.Query; @Repository public class StoreRepository { private final EntityManager em; public StoreRepository(EntityManager em) { this.em = em; } 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(); } public List<Store> findAll() { // 조건: 오브젝트 매핑은 @Entity 가 붙어야지만 가능하다 (디폴트 생성자를 호출) Query query = em.createNativeQuery("select * from store_tb order by id desc", Store.class); return query.getResultList(); } 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(); } }

StoreController

package com.metacoding.storev1.store; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import jakarta.servlet.http.HttpServletRequest; @Controller // IoC (제어의역전) -> HashSet public class StoreController { private StoreService storeService; public StoreController(StoreService storeService) { this.storeService = storeService; } @GetMapping("/") public String list(HttpServletRequest request) { // MVC List<Store> storeList = storeService.상품목록(); request.setAttribute("models", storeList); return "store/list"; } @GetMapping("/store/save-form") public String saveForm() { return "store/save-form"; } @GetMapping("/store/{id}") public String detail(@PathVariable("id") int id, HttpServletRequest request) { Store store = storeService.상세보기(id); request.setAttribute("model", store); return "store/detail"; } @GetMapping("/store/{id}/update-form") public String updateForm(@PathVariable("id") int id) { return "store/update-form"; } @PostMapping("/store/{id}/delete") public String delete(@PathVariable("id") int id) { return "redirect:/"; } @PostMapping("/store/save") public String save(@RequestParam("name") String name, @RequestParam("stock") int stock, @RequestParam("price") int price) { System.out.println("name" + name); System.out.println("stock" + stock); System.out.println("price" + price); storeService.상품등록(name, stock, price); return "redirect:/"; } @PostMapping("/store/{id}/update") public String update(@PathVariable("id") int id) { return "redirect:/store/1"; } }

StoreService

package com.metacoding.storev1.store; import java.util.List; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class StoreService { private StoreRepository storeRepository; public StoreService(StoreRepository storeRepository) { this.storeRepository = storeRepository; } @Transactional public void 상품등록(String name, int stock, int price) { storeRepository.save(name, stock, price); } public List<Store> 상품목록() { List<Store> storeList = storeRepository.findAll(); return storeList; } public Store 상세보기(int id) { Store store = storeRepository.findbyId(id); return store; } }
notion image
notion image

4. 상품 삭제

detail

{{>layout/header}} <section> <a href="/store/{{model.id}}/update-form">수정화면가기</a> <form action="/store/{{model.id}}/delete" method="post"> <button type="submit">삭제</button> </form> <div> 번호 : {{model.id}} <br> 상품명 : {{model.name}} <br> 상품가격 : {{model.price}}원 <br> 상품재고 : {{model.stock}}개 <br> </div> <form action="#"> <input type="hidden" value="{{model.id}}"> <input type="text" placeholder="당신은 누구인가요?"> <input type="text" placeholder="Enter 개수"> <button type="submit">구매</button> </form> </section> </body> </html>

StoreRepository

package com.metacoding.storev1.store; import java.util.List; import org.springframework.stereotype.Repository; import jakarta.persistence.EntityManager; import jakarta.persistence.Query; @Repository public class StoreRepository { private final EntityManager em; public StoreRepository(EntityManager em) { this.em = em; } 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(); } public List<Store> findAll() { // 조건: 오브젝트 매핑은 @Entity 가 붙어야지만 가능하다 (디폴트 생성자를 호출) Query query = em.createNativeQuery("select * from store_tb order by id desc", Store.class); return query.getResultList(); } 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(); } // 1 public void deleteById(int id) { Query query = em.createNativeQuery("delete from store_tb where id =?"); query.setParameter(1, id); query.executeUpdate(); } }

StoreController

package com.metacoding.storev1.store; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import jakarta.servlet.http.HttpServletRequest; @Controller // IoC (제어의역전) -> HashSet public class StoreController { private StoreService storeService; public StoreController(StoreService storeService) { this.storeService = storeService; } @GetMapping("/") public String list(HttpServletRequest request) { // MVC List<Store> storeList = storeService.상품목록(); request.setAttribute("models", storeList); return "store/list"; } @GetMapping("/store/save-form") public String saveForm() { return "store/save-form"; } @GetMapping("/store/{id}") public String detail(@PathVariable("id") int id, HttpServletRequest request) { Store store = storeService.상세보기(id); request.setAttribute("model", store); return "store/detail"; } @GetMapping("/store/{id}/update-form") public String updateForm(@PathVariable("id") int id) { return "store/update-form"; } // 2 @PostMapping("/store/{id}/delete") public String delete(@PathVariable("id") int id) { storeService.상품삭제(id); return "redirect:/"; } @PostMapping("/store/save") public String save(@RequestParam("name") String name, @RequestParam("stock") int stock, @RequestParam("price") int price) { System.out.println("name" + name); System.out.println("stock" + stock); System.out.println("price" + price); storeService.상품등록(name, stock, price); return "redirect:/"; } @PostMapping("/store/{id}/update") public String update(@PathVariable("id") int id) { return "redirect:/store/1"; } }

StoreService

package com.metacoding.storev1.store; import java.util.List; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class StoreService { private StoreRepository storeRepository; public StoreService(StoreRepository storeRepository) { this.storeRepository = storeRepository; } @Transactional public void 상품등록(String name, int stock, int price) { storeRepository.save(name, stock, price); } public List<Store> 상품목록() { List<Store> storeList = storeRepository.findAll(); return storeList; } public Store 상세보기(int id) { Store store = storeRepository.findbyId(id); return store; } // 3 @Transactional // insert, delete, update 시에 사용: 함수 종료 시 commit 됨 public void 상품삭제(int id) { // 상품 있는지 확인 Store store = storeRepository.findbyId(id); // 있으면 삭제 if (store == null) { throw new RuntimeException("상품 없는데 왜 삭제?"); } storeRepository.deleteById(id); } }
notion image
notion image
notion image
 

5. 상품 수정

update-form

{{>layout/header}} <section> <form action="/store/{{model.id}}/update" method="post" > <input type="text" name="name" value="{{model.name}}"><br> <input type="text" name="stock" value="{{model.stock}}"><br> <input type="text" name="price" value="{{model.price}}"><br> <button type="submit">상품수정</button> </form> </section> </body> </html>

StoreRepository

package com.metacoding.storev1.store; import java.util.List; import org.springframework.stereotype.Repository; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestParam; import jakarta.persistence.EntityManager; import jakarta.persistence.Query; @Repository public class StoreRepository { private final EntityManager em; public StoreRepository(EntityManager em) { this.em = em; } 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(); } public List<Store> findAll() { // 조건: 오브젝트 매핑은 @Entity 가 붙어야지만 가능하다 (디폴트 생성자를 호출) Query query = em.createNativeQuery("select * from store_tb order by id desc", Store.class); return query.getResultList(); } 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(); } public void deleteById(int id) { Query query = em.createNativeQuery("delete from store_tb where id =?"); query.setParameter(1, id); query.executeUpdate(); } // 1 public void update(@PathVariable("id") int id, @RequestParam("name") String name, @RequestParam("stock") int stock, @RequestParam("price") 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(); } }

StoreController

package com.metacoding.storev1.store; import java.util.List; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import jakarta.servlet.http.HttpServletRequest; @Controller // IoC (제어의역전) -> HashSet public class StoreController { private StoreService storeService; public StoreController(StoreService storeService) { this.storeService = storeService; } @GetMapping("/") public String list(HttpServletRequest request) { // MVC List<Store> storeList = storeService.상품목록(); request.setAttribute("models", storeList); return "store/list"; } @GetMapping("/store/save-form") public String saveForm() { return "store/save-form"; } @GetMapping("/store/{id}") public String detail(@PathVariable("id") int id, HttpServletRequest request) { Store store = storeService.상세보기(id); request.setAttribute("model", store); return "store/detail"; } // 2 @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"; } @PostMapping("/store/{id}/delete") public String delete(@PathVariable("id") int id) { storeService.상품삭제(id); return "redirect:/"; } @PostMapping("/store/save") public String save(@RequestParam("name") String name, @RequestParam("stock") int stock, @RequestParam("price") int price) { System.out.println("name" + name); System.out.println("stock" + stock); System.out.println("price" + price); storeService.상품등록(name, stock, price); return "redirect:/"; } @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; } }

StoreService

package com.metacoding.storev1.store; import java.util.List; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class StoreService { private StoreRepository storeRepository; public StoreService(StoreRepository storeRepository) { this.storeRepository = storeRepository; } @Transactional public void 상품등록(String name, int stock, int price) { storeRepository.save(name, stock, price); } public List<Store> 상품목록() { List<Store> storeList = storeRepository.findAll(); return storeList; } public Store 상세보기(int id) { Store store = storeRepository.findById(id); return store; } // 3 @Transactional // insert, delete, update 시에 사용: 함수 종료 시 commit 됨 public void 상품삭제(int id) { // 상품 있는지 확인 Store store = storeRepository.findById(id); // 있으면 삭제 if (store == null) { throw new RuntimeException("상품 없는데 왜 삭제?"); } storeRepository.deleteById(id); } // 3 @Transactional public void 상품수정(int id, String name, int stock, int price) { // 상품 있는지 확인 Store store = storeRepository.findById(id); // 삭제 if (store == null) { throw new RuntimeException("상품이 없는데 왜 삭제?"); } storeRepository.update(id, name, stock, price); } // 되면 commit, 안 되면 rollback }
notion image
notion image
notion image
notion image
notion image
Share article

parangdajavous