Spring MVC - 1

hyuko·2023년 3월 12일
0

인프런강의

목록 보기
1/1

MVC 패턴을 활용한 간단한 페이지

  • 프로젝트 선택
    • Project: Gradle-groovy
    • Language: Java
    • Spring Boot: 2.7.x
  • Project Metadata
    • Group: hello
    • Artifact: item-service
    • Name: item-service
    • Package name: hello.itemservice
    • Packaging: Jar
    • Java version: 11
  • Dependencies: Spring Web, Thymeleaf, Lombok

요구사항 분석


상품을 관리할 수 있는 서비스를 만들자!
여기서 중요한 것은 상품입니다 .

그러므로 우리의 도메인은 상품 위주로 갑니다.

상품 도메인 모델

  • 상품 ID
  • 상품명
  • 가격
  • 수량

상품 관리 기능

  • 상품 목록
  • 상품 상세
  • 상품 등록
  • 상품 수량

설계시작


요즘의 백엔드는 RESTful API 로 작성하는 것이 트렌드 이긴 하나
이 간단한 페이지를 만들 때에는 SSR (Server Side Randering)을 이용해서 개발을 하도록 하겠습니다.

위의 그림을 토대로 도메인 서비스를 개발 해보도록 하겠습니다.
여기서 우리는 간단한 페이지이기 때문에 controller와 repository만 놔두고 service는 생성하지 않습니다.

repository와 entity 객체


  • Item 이라는 객체를 생성해 줍니다.
import lombok.Getter;
import lombok.Setter;

@Getter @Setter
public class Item {

    private Long id;
    private String itemName;
    private Integer price;
    private Integer quantity;

    public Item(){}

    public Item(String itemName, Integer price, Integer quantity) {
        this.itemName = itemName;
        this.price = price;
        this.quantity = quantity;
    }
}
  • repository 패키지를 도메인 하위에 만들어주고 그 아래에 ItemRepository를 생성합니다.
import hello.itemservice.domain.item.Item;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository
public class ItemRepository {

    private static final Map<Long, Item> store = new HashMap<>(); // static
    private static long sequence = 0L; // static

	<!-- 1 -->
    public Item save(Item item) {
        item.setId(++sequence);
        store.put(item.getId(), item);
        return item;
    }
	
    <!-- 2 -->
    public Item findById(Long id) {
        return store.get(id);
    }
	
    <!-- 3 -->
    public List<Item> findAll() {
        return new ArrayList<>(store.values());
    }
	
    <!-- 4 -->
    public void update(Long itemId, Item updateParam) {
        Item findItem = findById(itemId);
        findItem.setItemName(updateParam.getItemName());
        findItem.setPrice(updateParam.getPrice());
        findItem.setQuantity(updateParam.getQuantity());
    }

    public void clearStore() {
        store.clear();
    }
}
  1. repository를 생성할 때 생성자에 Item 을 주입 받아 줍니다. 주입을 받으면서 item의 id를 set을 해주는데 이때 sequence 값을 하나씩 늘려주면서 넣어줍니다. 그리고 그 아이디 값을 store라는 Map
    즉, 우리가 메모리 db로 쓰일 곳에 저장해줍니다.

  2. item의 id값을 받아와서 저장되어 있는 store의 아이디 값과 비교해서 객체를 반환합니다.

  3. 모든 객체를 가져오는 방식입니다.
    item을 List에 담아 모두 반환합니다.

  4. item id를 받고 바꿀 내용을 받아서,
    받은 id값이 일단 존재하는지 findById를 통해 찾은 객체에다가 같이 받은 바꿀 내용을 담은 item을 바꿔주는 형식입니다.

Controller


  • 여기서 쓰이는 우리 컨트롤러는 뷰를 뿌려주는 역할을 합니다.
import hello.itemservice.domain.item.Item;
import hello.itemservice.domain.item.repository.ItemRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.annotation.PostConstruct;
import java.util.List;

@Controller
@RequestMapping("/basic/items")
@RequiredArgsConstructor
public class BasicItemController {

    private final ItemRepository itemRepository;

    @GetMapping
    public String items(Model model) {
        List<Item> items = itemRepository.findAll();
        model.addAttribute("items", items);
        return "basic/items";
    }

    @GetMapping("/{itemId}")
    public String item(@PathVariable long itemId, Model model) {
        Item item = itemRepository.findById(itemId);
        model.addAttribute("item", item);
        return "basic/item";
    }

    @GetMapping("/add")
    public String addForm() {
        return "basic/addForm";
    }

//    @PostMapping("/add")
    public String addItemV1(@RequestParam String itemName,
                       @RequestParam int price,
                       @RequestParam Integer quantity,
                       Model model) {
        Item item = new Item();
        item.setItemName(itemName);
        item.setPrice(price);
        item.setQuantity(quantity);

        itemRepository.save(item);
        model.addAttribute("item", item);

        return "basic/item";
    }

//    @PostMapping("/add")
    public String addItemV2(@ModelAttribute("item") Item item) {

        itemRepository.save(item);
//      model.addAttribute("item", item); //자동으로 모델을 생성해서 넣어준다. 그래서 생략가능

        return "basic/item";
    }

//    @PostMapping("/add")
    public String addItemV3(@ModelAttribute Item item, Model model) {

        itemRepository.save(item);
//      model.addAttribute("item", item); //자동으로 모델을 생성해서 넣어준다. 그래서 생략가능

        return "basic/item";
    }

//    @PostMapping("/add")
    public String addItemV4(Item item) {

        itemRepository.save(item);
//      model.addAttribute("item", item); //자동으로 모델을 생성해서 넣어준다. 그래서 생략가능

        return "basic/item";
    }

//    @PostMapping("/add")
    public String addItemV5(Item item) {
        itemRepository.save(item);

        return "redirect:/basic/items/" + item.getId();
    }

    @PostMapping("/add")
    public String addItemV6(Item item, RedirectAttributes redirectAttributes) {
        Item savedItem = itemRepository.save(item);
        redirectAttributes.addAttribute("itemId", savedItem.getId());
        redirectAttributes.addAttribute("status", true);
        return "redirect:/basic/items/{itemId}";
    }

    @GetMapping("/{itemId}/edit")
    public String editForm(@PathVariable Long itemId, Model model) {
        Item item = itemRepository.findById(itemId);
        model.addAttribute("item", item);

        return "basic/editForm";
    }

    @PostMapping("/{itemId}/edit")
    public String edit(@PathVariable Long itemId, @ModelAttribute Item item) {
        itemRepository.update(itemId, item);

        return "redirect:/basic/items/{itemId}";
    }

    /**
     *  미리 생성해놓기 위해서 만듬
     */
    @PostConstruct
    public void init() {
        itemRepository.save(new Item("itemA", 10000, 10));
        itemRepository.save(new Item("itemB", 20000, 20));
    }
}

뷰 템플릿과 컨트롤러에 대한 설명은
다음 포스트에서 이어가도록 하겠습니다.
자세한 코드는 https://github.com/hyuk12/spring-mvc1/tree/main/item-service

profile
백엔드 개발자 준비중

0개의 댓글