Entity와 DTO차이
Entity와 DTO의 차이
Entity
- 데이터베이스에 저장되는 데이터 객체, 데이터베이스와 직접적으로 연결
- 실제 DB테이블과 매핑되는 핵심 클래스, 해당 테이블에 존재하는 모든 컬럼들을 필드로 가진다.
- 데이터베이스의 영속성(persistence)의 목적으로 사용되는 객체
- 요청이나 응답값을 전달하는것은 부적절하다.
- 이유 : 많은 서비스 클래스와 비즈니스 로직들이 Entity클래스를 기준으로 동작하기 때문에 클래스에 영향을 줄 수있다.
- Setter 메서드의 사용 지양
- 이유 : setter로 접근이 가능하면 객체의 일관성, 안전성을 보장하기 힘들다.
- 따라서 Entity는 setter 대신 생성자(Constructor) 또는 Builder를 사용한다.
- 생성자(Constructor)를 이용해서 초기화하는 경우 : 불변 객체로 활용할 수 있고, 불변 객체로 만들면 데이터를 전달하는 과정에서 데이터가 변조되지 않음을 보장한다.
- Builder를 사용하는 경우 : 멤버 변수가 많아지더라도 어떤 값을 어떤 필드에 넣는지 코드를 통해 확인할 수 있고, 필요한 값만 넣는 것이 가능하다
DTO
- 클라이언트와 서버 간 데이터 전송을 위해 일회성으로 데이터를 주고 받는 용도로 설계된 객체
- getter, setter 메서드를 포함하며, 이외의 비즈니스 로직은 포함하지 않는다.
자바는 데이터 자동화 처리를 위해 리플렉션 기법을 사용한다. 예시의 DTO에서 프로퍼티(Property)가 name이라면 name의 키값으로 들어온 데이터는 리플렉션 기법으로 setter를 실행시켜 데이터를 넣을 수 있다.
(직접 setter를 요청하는 것이 아닌 프레임워크 내부에서 setter가 실행된다는 것이 중요한 포인트)
특히 레이어 간(View에서 Controller로 이동)에 데이터를 넘길 때 DTO를 사용하면 편하다는 것이 이런 이유이다.
(View에서 name 필드 값을 프로퍼티에 맞춰서 넘겼을 때, 받아야 하는 곳에서 하나하나 처리하는 것이 아니라 name 속성의 이름과 매칭 되는 프로퍼티에 자동적으로 DTO가 인스턴스화 되어 MemberDTO의 자료형으로 값을 받을 수 있다.)
출처 : https://wildeveloperetrain.tistory.com/101
Entity와 DTO를 분리하는 이유
1. 명확성 : Entity는 데이터베이스와 직접적으로 상호작용하지만 DTO는 서비스계층과 컨트롤러 계층 간의 데이터 전송을 담당한다. 이렇게 역할을 분리함으로써 각자의 역할이 명확하게 구분된다.
2. 데이터 보안 : Entity는 데이터베이스와 직접적으로 관련된 정보가 포함될 수 있다. 이러한 정보는 외부에 노출되지않도록 해야 한다. DTO를 통해 외부에 노출되는 데이터를 제어할 수 있다.
3. Entity구조변경이 있어도 DTO는 영향을 최소화한다.
*외부에 노출되는 데이터 : 클라이언트와 서버 간의 통신을 위해 클라이언트에서 서버로 전송되거나 서버에서 클라이언트로 전송되는 데이터
ex) 클라이언트에서 회원가입을 요청할 때, 사용자의 아이디, 비밀번호, 이메일 등의 정보를 서버에 전송해야 한다. 이때 클라이언트에서 서버로 전송되는 데이터는 JSON 형식으로 표현될 수 있으며, 해당 데이터의 구조와 형식은 회원가입 요청을 처리하는데 사용되는 DTO에 의해 정의된다. 따라서 이 데이터는 외부에 노출되는 데이터다.
Entity와 DTO 분리 장점
1. Entity를 보호한다.
Entity를 사용자에게 노출하면 원하지 않는 상황에서 자원의 속성이 변경될 가능성이 있다. 그리고 엔티티를 UI계층에 노출하는 것은 테이블 설계를 화면에 공개하는 것이나 다름없기 때문에 보안상으로도 바람직하지 못한 구조가 된다.
또한 dto는 setter를 허용하지만 entity에서 setter는 무분별하게 사용하면 안된다.
2, 화면에 필요한 데이터를 선별할 수 있다.
예를 들어 회원가입을 할 때는 아이디, 비밀번호, 이메일, 이름 정보만 작성하면 된다. 하지만 도메인 객체 User는 그 이상의 속성을 가지고 있을 것이다. 필요 이상으로 사용자가 가지고 있는 다른 속성들까지 항상 데이터 전송에 참여하게 되는 것이다. (보안에도 안좋고 속도도 느려짐)
3. 순환참조를 방지한다.
JPA에서 양방향 참조된 엔티티를 controller에서 반환하면, 순환참조가 발생하게 된다. 결국 무한 루프에 빠져 스택오버 플로우가 발생한다. JPA 에서 순환참조를 해결하려면 @JsonManagedReference와 @JsonBackReference을 사용하거나, @JsonIgnore을 쓰거나 하는 방법도 있지만 DTO를 사용하는 것이 안전하고 가독성이 좋다.
4. validation 코드와 모델링 코드를 분리할 수 있다.
Entity에서 @NotNull, @NotEmpty, @NotBlank 등과 같은 요청에 대한 값의 validation코드가 들어간다면 엔티티 클래스는 더 복잡해지고 그만큼 가독성이 저하된다. 각각의 요청에 필요한 validation을 DTO에서 정의한다면, 엔티티 클래스를 좀 더 모델링과, 비즈니스 로직에만 집중되도록 만들 수 있다.
Entity와 DTO 분리 단점
중복코드가 있고 개발 시간이 증가한다는 단점이 있지만 대규모 프로젝트일수록 분리하는 것이 적합하다.
VO
VO는 DTO와 동일한 개념이나 read only 속성만 갖는 차이점이 있다.
참고 자료 출처 :
https://wildeveloperetrain.tistory.com/101