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

만드는 서비스 미리보기

핵심 기능은 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 ]

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

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

[ OrderRepository ]

[ OrderService ]

- 로직
주문(Order) 생성
주문(Order) 취소
Order와 OrderItem 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콘솔을 킬 필요가 없음)