출처 : 이동욱 개발자님 [스프링 부트와 AWS로 혼자 구현하는 웹서비스]
내가 보려고 적는 기능 설명들
1. domain 패키지
도메인을 담을 패키지이다.
💡 도메인이란?
→ 게시글, 댓글, 회원, 정산, 결제 등 소프트웨어에 대한 요구사항
혹은 문제 영역이다.
🚨 기존에 MyBatis와 같은 쿼리 매퍼를 사용했다면,
dao 패키지를 떠올리겠지만, dao 패키지와는 결이 다르다.
그간 xml에 쿼리를 담고, 클래스는 오로지 쿼리의 결과만 담던 일들이
모두 도메인 클래스라고 불리는 곳에서 해결된다.
2. @NoArgsConstructor
기본 생성자 자동 추가
3. Entity 클래스에는 Setter 메소드가 없다.
해당 클래스의 인스턴스 값들이 언제 어디서 변해야 하는지 코드상으로 명확하게 구분하기 위해.
🚨 잘못된 사용 예
public class Order {
public void setStatus(boolean status) {
this.status = status;
}
}
public void 주문서비스의_취소이벤트() {
order.setStatus(false);
}
⭐ 올바른 사용 예
public class Order {
public void cancelOrder() {
this.status = false;
}
}
public void 주문서비스의_취소이벤트() {
order.cancelOrder();
}
4. Repository 인터페이스
보통 MyBatis에서 Dao라고 불리는 DB Layer 접근자이다.
JPA에선 Repository라고 부르며, 인터페이스로 생성한다.
→ 단순히 인터페이스를 생성 후, JpaRepository<Entity 클래스, PK 타입>를 상속하면
기본적인 CRUD 메소드가 자동으로 생성된다.
🚨 @Repository를 추가할 필요도 없다.
→ Entity 클래스와 기본 Entity Repository는 함께 위치해야 한다.
둘은 아주 밀접한 관계이고,
Entity 클래스는 기본 Repository 없이는 제대로 역할을 할 수가 없기 때문.
💡 Entity 클래스와 기본 Repository는 함께 움직여야 하므로
도메인 패키지에서 함께 관리한다.
5. OOORepositry.save
테이블 OOO에 insert / update 쿼리를 실행한다.
id 값이 있다면 update가, 없다면 insert 쿼리가 실행된다.
6. OOORepositry.findAll
테이블 OOO에 있는 모든 데이터를 조회해오는 메소드이다.
등록 / 수정 / 조회 API 만들기
API를 만들기 위해 총 3개의 클래스가 필요하다.
- Request 데이터를 받을 Dto
- API 요청을 받을 Controller
- 트랜잭션, 도메인 기능 간의 순서를 보장하는 Service
🚨 오해
Service에서 비즈니스 로직을 처리해야 한다는 것.
💡 하지만 전혀 그렇지 않다.
Serive는 트랜잭션, 도메인 간 순서 보장의 역할만 한다.
그럼 비즈니스 로직은 누가 처리하나?
각 영역 소개
1. Web Layer
● 흔히 사용하는 컨트롤러(@Controller)와 JSP / Freemarker 등의 뷰 템플릿 영역이다.
● 이외에도 필터(@Filter), 인터셉터, 컨트롤러 어드바이스(@ControllerAdvice) 등
외부 요청과 응답에 대한 전반적인 영역이다.
2. Service Layer
● @Service에 사용되는 서비스 영역이다.
● 일반적으로 Controller와 Dao의 중간 영역에서 사용된다.
● @Transactional이 사용되어야 하는 영역이기도 하다.
3. Repository Layer
● Database와 같이 데이터 저장소에 접근하는 영역이다.
● Dao(Data Access Object) 영역으로 이해하면 쉽다.
4. Dtos
● Dto(Data Transfer Object)는 계층 간에 데이터 교환을 위한 객체이며,
Dtos는 이들의 영역이다.
● 예를 들어, 뷰 템플릿 엔진에서 사용될 객체나
Repository Layer에서 결과로 넘겨준 객체 등이 이들을 이야기한다.
5. Domain Model
● 예를 들어, 택시 앱이라고 하면
배차, 탑승, 요금 등이 모두 도메인이 될 수 있다.
● @Entity가 사용된 영역 역시 도메인 모델이라고 이해하면 된다.
● 다만, 무조건 데이터베이스의 테이블과 관계가 있어야 하는 것은 아니다.
● VO처럼 값 객체들도 이 영역에 해당하기 때문.
Web(Controller), Service, Repository, Dto, Domain
이 5가지 레이어에서 비즈니스 처리를 담당해야 할 곳은 어디일까?
바로 Domain이다.
Dto 클래스
🚨 절대로 Entity 클래스를 Request / Response 클래스로 사용해서는 안 된다.
Entity 클래스는 데이터베이스와 맞닿은 핵심 클래스이다.
Entity 클래스를 기준으로 테이블이 생성되고, 스키마가 변경된다.
화면 변경은 아주 사소한 기능 변경인데,
이를 위해 테이블과 연결된 Entity 클래스를 변경하는 것은 너무 큰 변경이다.
수많은 서비스를 클래스나 비즈니스 로직들이 Entity 클래스를 기준으로 동작한다.
Entity 클래스가 변경되면 여러 클래스에 영향을 끼치지만,
Request와 Response용 Dto는 View를 위한 클래스라 정말 자주 변경이 필요하다.
View Layer와 DB Layer의 역할 분리를 철저하게 하는 게 좋다.
꼭 Entity 클래스와 Controller에서 쓸 Dto는 분리해서 사용하애 한다.
@Transactional(readonly = true)
트랜잭션 범위는 유지하되,
조회 기능만 남겨두어 조회 속도가 개선되기 때문에
등록, 수정, 삭제 기능이 전혀 없는 서비스 메소드에서 사용하는 것을 추천한다.
'Spring > 그 외' 카테고리의 다른 글
[Spring] 왜 스프링을 쓰는가? (특징 & 계층 구조) (0) | 2023.01.23 |
---|---|
Spring(스프링) 주요 어노테이션 정리 (0) | 2023.01.22 |
Dto, Controller, Service (0) | 2023.01.07 |
domain, JpaRepository (0) | 2023.01.07 |
스프링 시큐리티와 OAuth 2.0으로 로그인 기능 구현하기 (0) | 2023.01.04 |