💡 본 게시글은 김영한님의 인프런(Inflearn) 강의 실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발에 대해 공부하고, 정리한 내용입니다.
1. 상품 도메인 개발
1) 구현 기능
- 상품 등록
- 상품 목록 조회
- 상품 수정
2) 구현 순서
- 상품 엔티티 개발 (비즈니스 로직 추가)
- 상품 리포지토리 개발
- 상품 서비스 개발
- 상품 기능 테스트
3) 상품 엔티티 개발 (비즈니스 로직 추가)
(1) 상품 엔티티 코드
package jpabook.jpashop.domain.item;
import jpabook.jpashop.exception.NotEnoughStockException;
import lombok.Getter;
import lombok.Setter;
import jpabook.jpashop.domain.Category;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "dtype")
@Getter @Setter
public abstract class Item {
@Id @GeneratedValue
@Column(name = "item_id")
private Long id;
private String name;
private int price;
private int stockQuantity;
@ManyToMany(mappedBy = "items")
private List<Category> categories = new ArrayList<Category>();
//==비즈니스 로직==//
public void addStock(int quantity) {
this.stockQuantity += quantity;
}
public void removeStock(int quantity) {
int restStock = this.stockQuantity - quantity;
if (restStock < 0) {
throw new NotEnoughStockException("need more stock");
}
this.stockQuantity = restStock;
}
}
(2) 예외 추가
package jpabook.jpashop.exception;
public class NotEnoughStockException extends RuntimeException {
public NotEnoughStockException() {
}
public NotEnoughStockException(String message) {
super(message);
}
public NotEnoughStockException(String message, Throwable cause) {
super(message, cause);
}
public NotEnoughStockException(Throwable cause) {
super(cause);
}
}
(3) 비즈니스 로직 분석
- addStock(): 파라미터로 넘어온 수만큼 재고를 늘립니다. 이 메서드는 재고가 증가하거나 상품 주문을 취소해서 재고를 다시 늘려야 할 때 사용됩니다.
- removeStock(): 파라미터로 넘어온 수만큼 재고를 줄입니다. 만약 재고가 부족하면
NotEnoughStockException
예외가 발생합니다. 주로 상품을 주문할 때 사용됩니다.
4) 상품 리포지토리 개발
(1) 상품 리포지토리 코드
package jpabook.jpashop.repository;
import jpabook.jpashop.domain.item.Item;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import java.util.List;
@Repository
@RequiredArgsConstructor
public class ItemRepository {
private final EntityManager em;
public void save(Item item) {
if (item.getId() == null) {
em.persist(item);
} else {
em.merge(item);
}
}
public Item findOne(Long id) {
return em.find(Item.class, id);
}
public List<Item> findAll() {
return em.createQuery("select i from Item i", Item.class).getResultList();
}
}
(2) 기능 설명
- save(): 상품 저장 메서드입니다.
- 신규 등록:
id
가 없으면 새로운 엔티티로 보고persist()
를 호출합니다. - 수정:
id
가 있으면 이미 DB에 저장된 엔티티로 보고merge()
를 호출하여 수정합니다.
- 신규 등록:
- findOne(): 특정 상품을 ID로 조회합니다.
- findAll(): 모든 상품 목록을 조회합니다.
5) 상품 서비스 개발
(1) 상품 서비스 코드
package jpabook.jpashop.service;
import jpabook.jpashop.domain.item.Item;
import jpabook.jpashop.repository.ItemRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class ItemService {
private final ItemRepository itemRepository;
@Transactional
public void saveItem(Item item) {
itemRepository.save(item);
}
public List<Item> findItems() {
return itemRepository.findAll();
}
public Item findOne(Long itemId) {
return itemRepository.findOne(itemId);
}
}
(2) 기능 설명
- saveItem(): 상품 저장 메서드로, 상품 리포지토리의
save()
메서드를 호출하여 상품을 저장합니다. - findItems(): 모든 상품 목록을 조회하는 메서드입니다.
- findOne(): 특정 상품을 ID로 조회하는 메서드입니다.
상품 서비스는 상품 리포지토리에 단순히 위임만 하는 클래스입니다.
6. 총 정리
- 상품 엔티티 개발
Item
엔티티는 상품의 속성(이름, 가격, 재고 수량)을 정의하고, 재고를 관리하는 비즈니스 로직을 포함합니다.addStock()
메서드로 재고를 증가시키고,removeStock()
메서드로 재고를 감소시킵니다. 재고가 부족할 경우NotEnoughStockException
예외가 발생하도록 합니다.
- 상품 리포지토리 개발
ItemRepository
는@Repository
와EntityManager
를 사용하여 상품 데이터를 관리합니다.save()
메서드는 상품의 등록과 수정을 모두 처리하며,findOne()
과findAll()
메서드를 통해 상품을 조회할 수 있습니다.@RequiredArgsConstructor
를 사용해EntityManager
를 주입받습니다.
- 상품 서비스 개발
ItemService
는@Service
와@Transactional
을 사용하여 상품 비즈니스 로직을 처리하고, 트랜잭션을 관리합니다.saveItem()
,findItems()
,findOne()
메서드를 통해 리포지토리에 있는 상품을 저장하고 조회하는 기능을 제공합니다. 서비스 계층은 리포지토리에 단순히 위임하는 역할을 합니다.
- 상품 기능의 비즈니스 로직 테스트
Item
엔티티의 비즈니스 로직(재고 추가 및 감소)은 상품 도메인에서 중요한 부분이므로, 이를 테스트하여 올바르게 동작하는지 확인해야 합니다. 상품의 등록, 수정, 조회 기능이 제대로 동작하는지 검증하는 것이 중요합니다.
- 트랜잭션 관리 및 성능 최적화
@Transactional(readOnly = true)
를 사용하여 읽기 전용 트랜잭션으로 설정하면, 플러시를 하지 않음으로써 약간의 성능 최적화를 할 수 있습니다. 상품 등록이나 수정과 같은 데이터 변경 작업에서는 읽기 전용 트랜잭션을 사용하지 않도록 주의해야 합니다.
- 예외 처리와 유효성 검증
NotEnoughStockException
과 같은 예외를 통해 재고 부족 상황을 처리하며, 이러한 예외 처리가 비즈니스 로직의 중요한 부분임을 이해하고, 이를 적절히 핸들링해야 합니다.
'Spring > 웹 애플리케이션 개발' 카테고리의 다른 글
06. 주문 도메인 개발 (0) | 2024.09.08 |
---|---|
04. 회원 도메인 개발 (0) | 2024.09.08 |
03. 애플리케이션 구현 준비 (2) | 2024.09.08 |
02. 도메인 분석 설계 (2) | 2024.09.08 |
01. 프로젝트 환경설정 (0) | 2024.09.08 |