[4] 스프링 부트와 JPA 활용 (3) - 아키텍처 구조 / Service, Repository 개발

김정욱·2021년 3월 18일
2
post-thumbnail
post-custom-banner

만드는 서비스 미리보기

  • 핵심 기능은 3가지
    • 회원(Member) 관련
    • 상품(Item) 관련
    • 주문(Order) 관련

아키텍처 구조

  • 가장 일반적으로 많이 사용하는 계층형 구조
    • Controller : 웹 계층
    • Service : 비즈니스 로직, 트랜잭션 처리
    • Repository : JPA로 DB에 직접 접근하는 계층
    • Domain : 엔티티가 모여있는 계층 (모든 계층에서 사용)
  • 개발 순서
    • Domain 생성
    • Repository 생성
    • Service 생성
    • Controller 생성

회원 도메인 개발

[ MemberRepository ]

  • Respository는 직접 DB에 접근하기 위해 JPA가 필요
    --> EntityManager 필요
  • @PersistenceContext
    : 과거에 직접 EMF에서 EM을 가져오는 것들을 모두 어노테이션으로 대체함
  • 나중에 Spring Data jpa를 통해 @PersistenceContext@Autowired로 대체할 수 있어서 결국은 Lombok@RequiredArgsConstructor를 쓸 수 있다

[ MemberService ]

  • 로직
    • 회원 가입(+ 아이디 중복검사 로직)
    • 전체 회원 조회
  • @Transactional
    • 과거에 em에서 transaction을 가져와서 시작 / 종료 했던 작업을 이 어노테이션으로 대체
    • DB를 사용하는 모든 작업은 각 Transaction 안에서 수행 되어야 한다! 반드시!
  • @RequiredArgsConstructor
    • Lombok을 사용해서 생성자 자동주입의 코드를 간결화 한 것
    • @AllArgsConstructor모든 필드를 주입하는데 상황에 따라 주입이 필요하지 않은 필드도 있기 때문에 일반적으로 필요한 것만 주입하는 이 옵션이 많이 쓰임

상품 도메인 개발

[ ItemDomain ]

  • Entity 자체비즈니스 로직을 추가
    • Service에서 추가할 수도 있지만, Entity에 추가하는 방법은 응집력을 높임
    • 이러한 패턴을 도메인 모델 패턴 이라고 함
      (Service 계층은 단순히 요청을 위임하는 역할만 수행)

[ ItemRepository ]

  • em.merge 부분은 추후 자세한 설명 예정

[ ItemService ]

  • 로직
    • 상품 등록
    • 상품 1개 조회
    • 상품 전체 조회
  • @Transactional(readOnly = true)
    • DB를 조회만 하는 메서드에 작성더티채킹처럼 수정과 같은 작업을 생략하여 속도를 향상시킬 수 있음
    • 보통 조회하는 기능이 많기 때문에 전체readOnly로 놓고 수정/삭제등의 메서드에 따로 @Transactional 을 지정

주문 도메인 개발

[ OrderDomain ]

  • 생성 메서드
    • Order 객체생성하는 메서드
    • Entity유지시키면 추후 변경이 있어도 이 부분만 수정하면 됨
    • 이렇게 Entity생성메서드를 따로 가지고 있는것이 좋음
    • 생성 메서드를 만든 경우에 다른 사람이 직접 Service에서 new로 객체를 생성하지 못하게 생성자protected로 막는것이 좋다
  • 비즈니스 로직
    • 주문 취소
  • 조회 로직
    • 전체 주문 가격 조회
      : 필드 간 연산을 통해 계산해야 하는 로직을 조회 메서드로 만듬

[ OrderItemDomain ]

  • 역시 생성 메서드Entity에 따로 유지

[ OrderRepository ]


[ OrderService ]

  • 로직
    • 주문(Order) 생성
    • 주문(Order) 취소
  • OrderOrderItem Entity생성메서드를 만들었기 때문에 그 외 생성을 막기 위해 기본 생성자protected로 막을 필요가 있다
    --> 혹은 롬복을 통해 기본생성자의 Access level을 수정할 수도 있음!
  • Order만 저장
    : Entity 설계시 내부에 Cascade 속성을 지정해서 연관 엔티티의 연쇄작용을 걸어주었기 때문
  • 주문 취소
    • jpa의 사용으로 주문 취소시 해당 객체를 찾은 뒤 변경해주기만 하면 됨
      (SQL이었으면 다시 DB저장하는 과정이 필요)
    • Dirty Checking으로 수정이 간편한 JPA

테스트 코드 작성

[ MemberServiceTest ]

  • @SpringBootTest
    : 스프링을 띄워서 테스트하기 위한 어노테이션
  • @Transactional
    : Test코드에 작성시 수행 후 자동 Rollback이 된다
  • @Rollback(false)
    : 자동 Rollback끄기 위한 어노테이션
  • JUnit4 --> JUnit5
    : 테스트 코드 프레임워크 JUnit 버전 upgrade기대 예외를 걸어주는 옵션 방식이 변경
  • Test 환경에서 test/resources/application.yml을 작성하면 Test환경에만 적용하는 설정파일을 둘 수 있다
    --> DB 정보들 빈칸으로 둘 경우 자동으로 h2의 메모리 버전으로 실행함
    (메모리 방식이라서 h2 db콘솔을 킬 필요가 없음)
profile
Developer & PhotoGrapher
post-custom-banner

0개의 댓글