Spring/SpringBoot

#5 멤버 - Service, Repository 구현

SK_MOUSE 2022. 4. 4. 17:25
Service 계층
: Controller와 교류하기 위해 Repository에서 값을 불러옴
private final 특정Repository repository
ItemService & OrderService
ItemService.java
OrderService.java
배송(Delivery) 생성
주문상품(OrderItem) 생성 =>
주문(Order)
생성
Repository 계층
private final EntityManager em
구현 메소드 :
ItemRepository & OrderRepository
ItemRepository.java 
OrderRepository.java

형광펜을 칠한 서비스와 레포지토리를 구현.

Service 계층

: Controller와 교류하기 위해 Repository에서 값을 불러옴

 

@Service

: 서비스 계층임을 명시

 

@Transactional

: 항상 트랜잭션 안에서 데이터를 변경해야함. readOnly 디폴트값 = false

 

@RequiredArgsConstructor

: 생성자 주입방식

 

구현 필드 :

private final 특정Repository repository : @Autowired를 사용해도 되지만, 생성자 어노테이션으로 자동 주입.

 

구현 메소드 :

  • join(Member member) : 레포지토리에 저장
  • findMembers() : 전체 멤버 get
  • findOne(Long memberId) : 하나의 멤버 get by id
  • validateDuplicateMember(Member member) : 중복 검사 예외처리
@Service @Transactional(readOnly = true)//항상 트랜잭션 안에서 데이터 변경해야함!!! @RequiredArgsConstructor//생성자주입 방식. public class MemberService { ​​​​/** * 회원 가입 */ ​​​​//@Autowired//없어도 요즘은 스프링이 자동으로 생성자로 주입 ​​​​private final MemberRepository memberRepository;//final 필수!! ​​​​//회원가입 ​​​​@Transactional//readOnly=false 디폴트값. ​​​​public Long join(Member member){ ​​​​​​​​validateDuplicateMember(member);//멤버 중복잇는지 확인하는 메소드 ​​​​​​​​memberRepository.save(member); ​​​​​​​​return member.getId(); ​​​​} ​​​​//중복멤버확인 ​​​​private void validateDuplicateMember(Member member) { ​​​​​​​​List<Member> findMembers = memberRepository.findByName(member.getName()); ​​​​​​​​if(!findMembers.isEmpty()){ ​​​​​​​​​​​​throw new IllegalStateException("이미 존재하는 회원입니다."); ​​​​​​​​} ​​​​} ​​​​//회원조회 ​​​​public List<Member> findMembers(){ ​​​​​​​​return memberRepository.findAll(); ​​​​} ​​​​public Member findOne(Long memberId){ ​​​​​​​​return memberRepository.findOne(memberId); ​​​​} }
더보기

ItemService & OrderService

 

ItemService.java

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

saveItem(Item item), findItems(), findOne(Long itemId)

위 메소드들은 ItemRepository에 있는 것들을 그대로 가져오는것에 불과한 메소드이다.

 

 

OrderService.java

@Service @Transactional(readOnly = true) @RequiredArgsConstructor public class OrderService { ​​​​private final OrderRepository orderRepository; ​​​​private final MemberRepository memberRepository;//회원 id 넘어와야함 ​​​​private final ItemRepository itemRepository;//상품 id 넘어와야함 ​​​​/** * 주문 */ ​​​​@Transactional ​​​​public Long order(Long memberId, Long itemId, int count){ ​​​​​​​​//엔티티조회 ​​​​​​​​Member member = memberRepository.findOne(memberId); ​​​​​​​​Item item = itemRepository.findOne(itemId); ​​​​​​​​//배송정보 생성 ​​​​​​​​Delivery delivery = new Delivery(); ​​​​​​​​delivery.setAddress(member.getAddress());//회원 배송지주소 ​​​​​​​​//주문상품 생성 ​​​​​​​​OrderItem orderItem = OrderItem.createOrderItem(item, item.getPrice(), count); ​​​​​​​​//주문 생성 ​​​​​​​​Order order = Order.createOrder(member, delivery, orderItem); ​​​​​​​​//주문 저장 ​​​​​​​​orderRepository.save(order);//cascade옵션때문에 자동으로 delivery와 orderItems가 자동으로 저장됨. ​​​​​​​​return order.getId(); ​​​​} ​​​​/** * 주문 취소 */ ​​​​@Transactional ​​​​public void cancelOrder(Long orderId){ ​​​​​​​​//주문 엔티티조회 ​​​​​​​​Order order = orderRepository.findOne(orderId); ​​​​​​​​//주문취소 ​​​​​​​​order.cancel(); ​​​​} ​​​​//검색 ​​​​/* public List<Order> findOrders(OrderSearch orderSearch){ return orderRepository.findAll(orderSearch); } */ }

이 부분이 조금 복잡하다.

 

주문을 생성하려면 OrderRepository를 가져오고,

 

order(Long memberId, Long itemId, int count) 메소드 :

Member의 Id와 Item의 Id를 가져와서 주문을 해야한다.

-> 배송(Delivery) 생성 : 회원id 넣어줌

-> 주문상품(OrderItem) 생성 => 주문(Order)에 넣어주어 생성

-> OrderRepository 저장

 

cancelOrder(Long orderId) 메소드 :

orderRepository에서 취소할 주문(order)를 가져와서 order객체의 cancel()메소드를 실행(수량 감소).

 

Repository 계층

@Repository

: 레포지토리 계층임을 명시

 

@RequiredArgsConstructor

: EntityManager(영속성 컨텍스트)에 생성자 주입(자동 주입 - @PersistenceContext, @Autowired 없어도됨)

 

 

구현 필드 :

private final EntityManager em : 영속성(영구히 데이터 저장) 관리

 

 

구현 메소드 :

  • save(Member member) : 영속성 컨텍스트에 저장
  •  findOne(Long id) : 하나의 멤버 get by id
  • findAll() : 전체 멤버 get
  • findByName(String name) : 멤버 이름으로 찾기
@Repository @RequiredArgsConstructor public class MemberRepository { ​​​​//@PersistenceContext//jpa에서 영속성 컨텍스트에 주입시켜주고 관리. ​​​​//@Autowired//spring boot 면 이걸로 대체가능 + RequiredArgs생성자로 대체. ​​​​private final EntityManager em;//final 필수 ​​​​public void save(Member member){//저장 ​​​​​​​​em.persist(member); ​​​​} ​​​​public Member findOne(Long id){//단건 조회 ​​​​​​​​return em.find(Member.class, id);//(타입,PK) ​​​​} ​​​​public List<Member> findAll(){//전체 조회 :JPQL 사용('엔티티'를 조회) ​​​​​​​​return em.createQuery("select m from Member m", Member.class) ​​​​​​​​​​​​​​​​.getResultList(); ​​​​} ​​​​public List<Member> findByName(String name){ ​​​​​​​​return em.createQuery("select m from Member m where m.name = :name", Member.class) ​​​​​​​​​​​​​​​​.setParameter("name", name) ​​​​​​​​​​​​​​​​.getResultList(); ​​​​} }

 

더보기

ItemRepository & OrderRepository

 

ItemRepository.java 

@Repository @RequiredArgsConstructor public class ItemRepository { ​​​​private final EntityManager em; ​​​​public void save(Item item) { ​​​​​​​​if (item.getId() == null) {//jpa저장 전까지 id값이 없음. ​​​​​​​​​​​​em.persist(item);//그러므로 저장하는거임 ​​​​​​​​} else {//이미 db에 등록되어있으면 ​​​​​​​​​​​​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(); ​​​​} }

 

OrderRepository.java

@Repository @RequiredArgsConstructor public class OrderRepository { ​​​​private EntityManager em; ​​​​public void save(Order order){ ​​​​​​​​em.persist(order); ​​​​} ​​​​public Order findOne(Long id){ ​​​​​​​​return em.find(Order.class, id); ​​​​} // public List<Order> findAll(OrderSearch orderSearch){} }

 

반응형