Spring/SpringBoot

#5 멤버 - Service, Repository 구현

SK_MOUSE 2022. 4. 4. 17:25
반응형

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

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){}

}

 

반응형