Entity와 DTO

Caesars·2022년 2월 21일
1

Springboot

목록 보기
2/5

Entity

  • Entity 는 DB 테이블에 존재하는 컬럼들을 필드로 가지는, DB 테이블과 매핑되는 객체입니다. 따라서 테이블이 가지지 않는 컬럼을 필드로 가져서는 안 됩니다.
  • Entity는 Request나 Response 값을 전달하는 클래스가 아닙니다.
  • 객체의 일관성, 안전성을 보장하기 위해 setter 메서드의 사용을 지양하고 다른 클래스를 상속하거나 인터페이스를 구현해서도 안됩니다.

DTO

  • DTO는 Layer 간 데이터 교환이 이루어질 수 있도록 하는 객체입니다.
  • Controller Layer에서는 Entity 대신 DTO를 사용해서 View Layer와 데이터를 교환하며, Controller 외에도 여러 레이어 사이에서 DTO를 사용할 수 있지만 주로 View와 Controller 사이에서 데이터를 주고받을 때 활용성이 높습니다.
  • VO(Value Object) 와는 DTO는 값을 수정할 수 있습니다. (권장하지는 않습니다)

DTO와 Entity 분리

  • 만약 DB로부터 조회된 Entity를 그대로 View로 넘기게 되면 비즈니스 로직 등 도메인 Model의 민감한 정보가 외부에 노출되게 됩니다. 또한 Model과 View가 강하게 결합되어, View의 요구사항 변화가 Model에도 영향을 미칩니다.
  • 이러한 문제를 해결하기 위해 별도의 DTO 를 사용해서 각 Layer 간 역할을 분리합니다.
  • Entity와 동일한 DTO를 생성하는 것이 무슨 의미가 있냐는 생각이 들지만 추후에 프로젝트가 확장되고 코드를 수정

DTO는 애플리케이션에 복잡성을 추가할 수 있지만 계층도 마찬가지입니다. DTO는 시스템의 값비싼 기능이며 무료로 제공되지 않습니다.


변환 위치?

보통 Service 또는 Controller 에서 변환 작업을 수행하게 되는데 정확히 정답은 없어보입니다. Service 또는 Controller Layer에서 수행해야 한다고 주장하는 각각의 이유가 나름 일리가 있어보입니다.

Service에서 처리 :

  • 프리젠테이션 계층(MVC-Controllers/View)에서 도메인 모델을 사용하는 경우 프리젠테이션 계층이 도메인과 밀접하게 연결되게 됩니다. 때문에 Service에서 변환해야 합니다.
  • Controller가 View에서 전달받은 DTO만으로 Entity를 구성하기 어려운 경우가 있다. (여러 부수적인 정보들을 조회하여 Domain 객체를 구성해야 하는 경우)

Controller에서 처리 :

  • dto는 주로 컨트롤러 레이어에 종속적이므로 다른 레이어에 영향을 주면 좋지 않습니다. 컨트롤러에서만 쓰이는 용도의 객체가 서비스까지 전파되지 않게 해야 합니다.

개인적으로는 Controller에서 처리하는게 더 적합하다고 생각하는데 상황에 맞게 변할수도 있겠네요.


예제 코드

DTO Class

import java.io.Serializable;

class EmployeeDto implements Serializable {
    private static final long serialVersionUID = 1L;
    private long id;
    private String firstName;
    private String lastName;
    private String email;
    
    //getter, setter
}

Entity Class

@Entity
@Table(name = "employees")
class Employee implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue
    private long id;
    @Column(length = 40, nullable = false)
    private String firstName;
    @Column(length = 40, nullable = false)
    private String lastName;
    @Column(length = 100, nullable = false)
    private String email;
}

gradle

implementation 'com.fasterxml.jackson.core:jackson-databind:2.0.1'

변환

// Conversion from Entity to DTO
private EmployeeDto convertToDto(Employee employee) {
    ObjectMapper mapper = new ObjectMapper();
    return mapper.convertValue(employee, new TypeReference<EmployeeDto>() {});
}

// Conversion from DTO to Entity 
private Employee convertToEntity(EmployeeDto employeeDto) {
    ObjectMapper mapper = new ObjectMapper();
    return mapper.convertValue(employeeDto, new TypeReference<Employee>() {});
}

참조

https://gmlwjd9405.github.io/2018/12/25/difference-dao-dto-entity.html
https://champcoder.com/entity-to-dto-and-dto-to-entity-conversion-in-spring-boot/
https://entityframework.net/knowledge-base/21554977/should-services-always-return-dtos--or-can-they-also-return-domain-models-

profile
잊기전에 저장

0개의 댓글