JPA

SpringBoot JPA 쇼핑몰 상품 서비스 개발

빈코 2022. 9. 14. 17:35

SpringBootJPA, Thymeleaf를 사용하여 간단한 쇼핑몰을 구현하려 합니다. 프로젝트 생성이나 Gradle 빌드는 깃허브 BincoShop을 참고해주세요! 포스팅은 도메인&테이블 설계 -> 엔티티 개발 -> 회원 서비스 -> 상품 서비스 -> 주문 서비스 순으로 진행됩니다. 포스팅의 잘못된 부분은 언제든 댓글로 남겨주시면 수정하겠습니다😀

 

로고
상품 서비스 개발

개요

회원 서비스에 이어서 상품 서비스를 개발합니다. 이전 포스팅과 비슷한 흐름이어서 간단하게 진행될 것 같습니다. 모든 포스팅은 김영한 님의 강의를 참고하였습니다😄

 

Entity 수정📔

@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<>();

    //==business logic==//

    /*
    stock 증가
    */
    public void addStock(int quantity) {
        this.stockQuantity += quantity;
    }

    /*
    stock 감소
     */
    public void removeStock(int quantity){
        int restStock = this.stockQuantity - quantity;
        if (restStock < 0 ){
            throw new NotEnoughStockException("need more stock");
        }
        this.stockQuantity = restStock;
    }
}

위 코드는 저번 포스팅에서 business logic만 추가한 코드입니다. 기존에는 Service 단에서 재고를 가져오고 set,get을 통해 로직을 진행했지만, 재고 수량이 증가하고 감소하는 로직은 응집도를 위해 Entity에 작성하였습니다. 

 

  • addStock() 메서드는 파라미터로 넘어온 수만큼 재고를 늘린다. 이 메서드는 재고가 증가하거나 상품 주문을 취소해서 재고를 다시 늘려야 할 때 사용한다.
  • removeStock() 메서드는 파라미터로 넘어온 수만큼 재고를 줄인다. 만약 재고가 부족하면 예외가 발생하고, 주로 상품을 주문할 때 사용한다.

 

public class NotEnoughStockException extends RuntimeException {

    public NotEnoughStockException() {
        super();
    }

    public NotEnoughStockException(String message) {
        super(message);
    }

    public NotEnoughStockException(String message, Throwable cause) {
        super(message, cause);
    }

    public NotEnoughStockException(Throwable cause) {
        super(cause);
    }

}

공용으로 사용할 Exception 클래스 작성

 

Repository📙

@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();
    }
}

 

@Repository@RequiredArgsConstructor 어노테이션 설명은 지난 포스팅에서 했으므로 넘어가겠습니다. save() 메서드는 매개변수로 Item을 넘겨받아서 해당 아이템의 Id가 없으면 persist, 있으면 merge를 진행합니다.

 

더티체킹과 병합을 진행하는데, 쉽게 말해 저장하려는 아이템이 DB에도 없으면 자연스럽게 저장(persist)하는 로직이고, 만약에 DB에 같은 아이템이 있으면 덮어 씌운다는 얘기입니다.(merge)

 

Dirty Checking&Merge를 잘모르신다면 이곳을 클릭하셔서 확인해주세요😄


findOne 메서드와 findAll 메서드는 회원 서비스와 많이 유사하기 때문에 설명은 생략하겠습니다.

 

Service📘

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class ItemService {

    private final ItemRepository itemRepository;

    @Transactional
    public void saveItem(Item item) {
        itemRepository.save(item);
    }

    @Transactional
    public void updateItem(Long itemId, Book param) {
        Item findItem = itemRepository.findOne(itemId); // 영속 상태
        findItem.setPrice(param.getPrice());
        findItem.setName(param.getName());
        findItem.setStockQuantity(param.getStockQuantity());
        findItem.setId(param.getId());
        // 더티 체킹 == 변경 감지
    }

    public List<Item> findItems() {
        return itemRepository.findAll();
    }

    public Item findOne(Long itemId){
        return itemRepository.findOne(itemId);
    }
}

 

Service단도 회원 서비스와 많이 유사합니다. 다른 한 부분은 상품 정보를 업데이트하는 로직이 추가되었습니다. updateItem 메서드를 보면 파라미터로 id 값을 받아서 조회를 하는데, 이때 조회된 아이템은 영속 상태이므로 따로 저장하거나 업데이트하는 코드 없이 끝나게 됩니다.

 

트랜잭션더티 체킹으로 인해 업데이트 코드가 따로 필요가 없는 것입니다😄

 

 


👨‍👩‍👦‍👦 오픈채팅방 운영

취업을 준비하는 예비 개발자분들을 위한 질문&답변할 수 있는 공간을 만들었습니다. 취업과 이직을 하기 위해서 어떤 걸 중점적으로 준비해야 하는지부터 포트폴리오&이력서 작성법 등 다양한 질문들을 받고 답변을 드립니다. 참여하셔서 다양한 정보 얻고 가시면 좋을 것 같네요😁

 

참여코드 : 456456

https://open.kakao.com/o/gVHZP8dg

 

비전공 개발자 취업 준비방(질문&답변)

#비전공 #개발자 #취업 #멘토링 #부트캠프 #국비지원 #백엔드 #프론트엔드 #중소기업 #중견기업 #자바 #Java #sql

open.kakao.com

 


👨‍💻 전자책 출간

아울러 제가  🌟비전공자에서 2년만에 보안 전문 중견기업으로 이직 한 방법들을 정리한 전자책을 출간 하게 되었습니다. 어떤 걸 공부해야 하는지, 이직을 위해서 무엇을 준비해야 하는지, 제가 받았던 기술 면접 리스트 등 다양한 목차로 구성되어 있습니다. 또한, 구매 시 1:1 채팅을 이용하여 포트폴리오 첨삭을 도와드리고 있습니다. 🐕전자책으로 얻은 모든 수익은 유기견 센터 '팅*벨 입양센터'에 후원될 예정입니다. 관심 있으신 분들은 아래 링크를 참고해주세요😁

https://kmong.com/gig/480954

 

비전공개발자 2년만에 중견기업 들어간 방법 | 14000원부터 시작 가능한 총 평점 0점의 전자책, 취

0개 총 작업 개수 완료한 총 평점 0점인 Binco의 전자책, 취업·이직 전자책 서비스를 0개의 리뷰와 함께 확인해 보세요. 전자책, 취업·이직 전자책 제공 등 14000원부터 시작 가능한 서비스

kmong.com


 

마치며

지금까지 상품 서비스를 개발하였습니다. 다음 포스팅은 주문 서비스를 개발할 예정입니다😀

 

관련 포스팅

SpringBoot JPA 쇼핑몰 도메인&테이블 설계

SpringBoot JPA 쇼핑몰 엔티티 개발 I

SpringBoot JPA 쇼핑몰 엔티티 개발 II

SpringBoot JPA 쇼핑몰 회원 서비스 개발

SpringBoot JPA 쇼핑몰 주문 서비스 I

SpringBoot JPA 쇼핑몰 주문 서비스 II

SpringBoot JPA 쇼핑몰 주문 검색 개발

 

Reference

스프링 부트와 JPA 활용 - 김영한

반응형