[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콘솔
을 킬 필요가 없음)