지나공 : 지식을 나누는 공간

스프링 부트와 AWS로 혼자 구현하는 웹서비스 정리 - Chapter 03 JPA로 데이터베이스 다루기 본문

Tech/Spring Boot

스프링 부트와 AWS로 혼자 구현하는 웹서비스 정리 - Chapter 03 JPA로 데이터베이스 다루기

해리리_ 2021. 1. 6. 23:13

 

이동욱님의 '스프링부트와 AWS로 혼자 구현하는 웹서비스'를 읽고 기록하고 싶은 내용을 정리했다.

 

JPA는 jpa 카테고리에서 자세하게 다루었으므로 기억하고 싶은 내용만 간단히 적을 예정이다.

 

 

1. 주요 어노테이션을 클래스에 가깝게 쓰자

 

한 클래스에 어노테이션을 여러 개 쓰는 경우가 많다. 그럴 때 순서는 중요할 수록 클래스명에 가깝게 쓰자.

 

 

@Getter와 같은 롬복 어노테이션은 코드를 단순화시키지만 필수 어노테이션은 아니다. 따라서 @Entity를 클래스에 가깝게 두자.

 

2. Entity 클래스에서는 절대 setter 메소드를 만들지 말자

 

현재 위에 첨부한 사진에는 Getter만 있고 Setter는 없다.

무작정 getter/setter를 생성하면 해당 클래스의 인스턴스 값들이 언제 어디서 변해야 하는지 코드에서 명확히 구분하기 어렵다. 그러므로 절대 엔티티에 setter를 만들지 말자. 

 

만약 해당 필드 값의 변경이 필요하면 명확하게 그 목적와 의도를 나타낼 수 있는 메소드를 추가하자.

예를 들어 주문 취소 메소드를 만든다고 하자. 주문을 취소/재주문 어느 것으로든지 바꿀 수 있는 set메소드를 쓰는 게 아니라 아예 '취소메소드'라는 이름으로 취소 이벤트를 하는 메소드를 만드는 것이다.

 

(X) 잘못된 예

public class Order{
	public void setStatus(boolean status){
    	this.status= status;
    }
}

public void 주문서비스_취소(){
	order.setStatus(false);
}

 

(O) 올바른 예

public class Order{
	public void cancelOrder(){
    	this.status = false;
    }
}

public void 주문서비스_취소(){
	order.cancelOrder();
}

 

 

 

set은 위와 같이 수정의 기능 말고도 값 저장의 역할을 한다.

set 메소드가 없으면 값을 어떻게 저장하는가? 이건 Builder를 활용한다. 필드값을 저장하는 순서가 달라져도 각 필드에 맞게 저장할 수 있다.

 

 

3. Entity 클래스와 기본 Entity Repository는 함께 위치해야 한다.

 

Entity 클래스는 기본 Repository 없이는 제대로 역할을 할 수 없다. 그러므로 둘을 함께 위치시키자.

 

프로젝트 규모가 커져서 도메인 별로 프로젝트를 분리해야 한다면 Entity 클래스와 기본 Repository는 함께 움직이도록 도메인 패키지에서 함께 관리한다.

 

함께 위치하는 Posts와 PostsRepository

 

 

* application.properties에 코드를 작성해서 실행된 쿼리 확인하기

 

 

* IDENTITY 타입의 경우, 데이터베이스 종류에 따라 dialect가 맞게 적용된다.

 

현재 H2 데이터베이스일 때는 아래와 같은 create문이 실행된다.

 

H2

 

application.properties에서 dialect를 MySQL로 바꿔서 실행해보면 아래와 같은 create문이 실행된다.

 

MySQL

 

 

4. 비즈니스 처리 담당은 Domain에서!

 

Web(Controller), Service, Repository, Dto, Domain 이 5개 layer 중 Domain이 비즈니스 로직을 담당하고 Service는 트랜잭션, 도메인 간 순서 보장의 역할만 한다. 기존에 서비스에서 비즈니스 처리를 하던 방식을 트랜잭션 스크립트라고 한다.

 

5. Entity 클래스를 request / response 클래스로 사용해서는 안 된다.

 

Entity 클래스는 데이터와 맞닿은 핵심 클래스로, 이 클래스를 기준으로 테이블이 생성되고 스키마가 변경된다. response나 request 처럼 화면에서의 변경은 사소한 기능의 변경이므로 이걸 위해 테이블과 바로 연결된 클래스를 변경하는 것은 너무 큰 변경이다.

 

Entity 클래스는 비즈니스 로직의 기준으로 동작하므로 이게 변경되면 다른 여러 클래스에 영향을 끼치는데에 반해 response와 request용 dto는 view를 위한 클래스라 정말 많은 변경이 일어난다. 그러므로 Controller에서 쓸 Dto와 Entity클래스는 반드시 분리해야 한다.

 

또한, 컨트롤러에서 결괏값으로 여러 테이블을 조인해서 주는 경우가 있는데 이럴 때는 Entity클래스 하나만으로 구현하기 어려우므로 Dto를 사용한다.

 

 

Posts 등록 API 테스트

 

 

 

@WebMvcTest를 쓰지 않은 이유

@WebMvcTest는 JPA기능이 작동하지 않고 Controller와 ControllerAdvice 등 외부 연동과 관련된 부분만 활성화되므로, 지금처럼 JPA 기능까지 테스트를 같이할 땐 @SpringBootTest, TestRestTemplate을 사용한다. TestRestTemplate으로 설정 시 자동으로 빈이 생성되고 RestTemplate의 처리가 가능하다. 사용하면 실제 서버가 동작하는 것처럼 테스트를 수행할 수 있다.

 

WebEnvironment.RANDOM_PORT를 통해 랜텀 포트 실행이 가능하다.

728x90
Comments