실전 활용1 JPA _개발(상품,)
상품 도메인 개발
상품 엔티티 개발
(구현 기능): ¹상품 등록 ²상품 목록 조회 ³상품 수정
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) //한테이블에 떄려박는 느낌으로.
@DiscriminatorColumn(name = "dtype") //SINGLE_TABLE 아래의 타입들을 찾고자
@Getter @Setter
//@Setter -> 핵심 비즈니스의 값을 변경할때 굳이 필요 없이 필요한 곳에서 메서드를 만들어야 함
//구현체를 가지기 위해- 추상클래스
public abstract class Item {
@Id
@GeneratedValue
@Column(name = "item_id") //pk 설정
private Long id;
.
.
.
private int stockQuantity; //재고수량
//--비즈니스 로직--/
//왜 이곳에?
//객체지향적으로 이 객체를 가지고 있는 쪽에서 메서드를 만드는 것이 가장 좋기 때문
/*
* 재고수량 증가 (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;
}
}
1) 비즈니스 로직 생성 _(재고수량 측정)
[이 강아지의 코딩공부, Gemini Kim블로그에서 setter를 언제 쓰면 좋을지 참고하였습니다!]
왜 @Setter
을 굳이 지양하고 비즈니스 로직을 해당 클레스에서 만들어야 할까?
📣) @Setter의 지양
jpa는 트랜젝션 안에서 Entity의 변경사항을 감지해 UPDATE SQL을 생성한다.
=> @Setter로 인해 UPDATE 기능이 수행되고 있었다.
=> 예측하지 못한 곳에서 update가 일어나면 일일히 Setter을 확인하는 불편이 생길 수 있다.
이러한 여러가지 관점으로 인해 이렇게 setter
을 대신해 메서드를 이용하여, 관련된 해당 클래스에 비즈니스 로직을 생성해주는 것이 좋다. 굳이 다른 클래스에서 setter
를 이용해 값을 하나하나 불러와 변경할 필요가 없게 된다.
상품 리포지토리
@Repository
@RequiredArgsConstructor
public class ItemRepository {
//스프링 데이터 jpa땜에
private final EntityManager em;
//*상품저장* item은 맨처음엔 id가 없음
public void save(Item item){
//맨 처음에는 id값이 없다 == 새로 생성한 객체
if(item.getId() == null){
em.persist(item); //신규로 등록하기
}else{//이미 등록되어 있는 것->DB에서 가져와서 저장된 엔티티를 수정한다 생각하자.
//자세한 것은 웹 뒤에서
em.merge(item);
}
}
public Item findOne(Long id){
return em.find(Item.class, id); //단건 조회니까 find() 쓰자
}
public List<Item> findAll(){
return em.createQuery("select i from Item i", Item.class)
.getResultList();
}
}
1)persist(), merge()
영속성 컨텍스트와 JPA에 관하여 이 Namjun Kim 블로그를 참조하였습니다.
- 맨처음
id
는 값이 없으므로save()
메서드에서는 id값을 확인 후em.persist()
로 최초 생성된 엔티티를 영속화 한다.
=> 즉 신규라고 생각, '신규등록'한다. - 그러나 id 값이 null이 아닌 경우
em.merge()
를 써준다. 이를 생각해보면 객체가 이미 등록되어 있다.
-> 그러므로 저장되어 있는 엔티티를 가져와 수정한다 생각하자...
상품 서비스
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class ItemService {
private final ItemRepository itemRepository;
@Transactional //위에 (readOnly)때문에 읽기전용이면 저장이 안됨.->쓰기로 바꿔줌
public void saveItem(Item item){
itemRepository.save(item);
}
public List<Item> findItems(){
return itemRepository.findAll();
}
public Item findOne(Long itemId){
return itemRepository.findOne(itemId);
}
}
상품 서비스는 단순히 상품 리포지토리에 위임한게 다이다.
✔ @Transactional(readOnly=true)
로 되어 있기 때문에 저장이 필요한 saveItem()
메서드만 따로 '읽기전용'에서 '쓰기전용'으로 바꿔주었다.
테스트는 회원 테스트와 비슷하므로 건너뛴다.
Author And Source
이 문제에 관하여(실전 활용1 JPA _개발(상품,)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@dabeen-jung/실전-활용1-JPA-개발상품저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)