Entity vs DTO vs VO 개념과 특징

2023. 11. 8. 00:45백엔드/Spring Boot

✏️  데이터를 처리할 때 사용되는 Entity와 DTO와 VO의 개념과 특징에 대하여 알아보자 

 

Entity 

 

개념

Entity는 객체 지향 프로그래밍에서 데이터를 표현하는 객체로 Java에서 데이터베이스와의 상호작용을 관리하기 위한 객체로 사용된다. Entity 클래스는 데이터베이스 테이블과 일치하는 구조를 가지며, 데이터베이스의 레코드를 나타낸다.

해당 클래스는 CRUD(데이터를 저장, 검색, 업데이트 및 삭제) 작업을 할 때 사용된다. 

 

특징

  • Entity 객체는 DB Table과 구조가 일치하며 Field는 테이블의 열(Column)과 일치하는데 이것을 ORM (Object-Relational Mapping)을 사용하여 자동으로 매핑할 수 있다. 
    * DB의 테이블 내에 존재하는 컬럼만을 속성(필드)으로 가져야 한다.
  • 테이블의 기본 키(primary key)를 나타내는 필드를 포함한다. 
  • @Entity 어노테이션을 final, enum, interface, inner 클래스에 사용할 수 없다. 
  • 데이터베이스와의 연결을 통해 영속성(데이터가 애플리케이션에서 생성, 수정된 후에도 데이터가 지속됨)을 보장하며, 데이터베이스와의 일관성을 유지한다. 
  • setter 메소드를 사용하면 객체의 상태를 언제든지 변경할 수 있으므로 상태불변성 유지를 위해 setter메서드를 사용하는 것을 지양하고 생성자를 통해 필수적인 데이터를 초기화하고, 필요한 데이터를 조회할 수 있는 getter 메서드를 사용하는 것을 지향해야 한다. 
  • 가장 Core한 객체라고도 불린다. 

 

예시코드

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class User {
    @Id
    private Long id;
    private String username;
    private String email;

    // Getter and Setter methods
    public Long getId() {
        return id;
    }


    public String getUsername() {
        return username;
    }

    
    public String getEmail() {
        return email;
    }

}

 

 

DTO (Data Transfer Object)

 

개념

DTO는 데이터 전송 객체로 데이터 전송을 위한 목적으로 사용된다. 

로직이 없으며 데이터의 저장 및 비즈니스 로직 처리보다는 데이터를 서로 다른 시스템과 계층 간에 전송하는 데 중점을 둔다.

DTO는 데이터를 구조화된 방식으로 전달하고, 데이터의 일부 또는 전체를 포함할 수 있다.

 

특징

  • 클라이언트 단과 직접 마주하는 계층에서는 Entity 대신 DTO를 사용해서 데이터를 교환한다. 
  • getter, setter 메서드를 포함하며, 이 외의 비즈니스 로직은 포함하지 않는다. 
    setter 메소드를 포함하고 있기 때문에 값이 변할 수 있다. 
  • DTO는 주로 데이터의 조회와 전송을 위해 사용된다. 
    Ex. 클라이언트 애플리케이션과 서버 간의 데이터 교환, 웹 요청 및 응답, 서비스 간 통신 등
  • 주로 비동기 처리를 할 때 사용한다. 
  • 데이터를 효율적으로 전송하고 처리하기 위해 데이터를 구조화된 형식으로 포함하며 필요한 데이터 필드 만을 포함 한다. 
  • DTO 내의 데이터는 읽기 전용이며 변경되어야 하지 않아야 하므로 DTO 객체는 주로 데이터의 불변성을 유지한다. 

 

예시코드

public class UserDTO {
    private Long id;
    private String username;
    private String email;

    // 생성자
    public UserDTO(Long id, String username, String email) {
        this.id = id;
        this.username = username;
        this.email = email;
    }

    // Getter 메서드
    public Long getId() {
        return id;
    }

    public String getUsername() {
        return username;
    }

    public String getEmail() {
        return email;
    }
}

 

VO (Value Object)

 

개념

VO는 값을 나타내는 객체로, 데이터의 불변성과 값을 변경할 수 없도록 설계된다.

도메인 모델에서 사용되며 데이터의 일부 또는 전체를 포함하는 객체로서 데이터를 구조화하고 유지할 목적으로 사용된다. 

 

특징 

    • 불변성 : 한 번 생성된 객체는 사용하는 도중에 변경 불가능하며 오직 읽기만 가능한 Read-Only 특징을 가지고 있다. 
      데이터의 값을 나타내며 수정하거나 변경하지 않는다.
    • DTO와 유사하지만 getter 메소드만을 가지고 있다.
    • 값 동등성 : equals()와 hashCode()를 오버라이딩해서 모든 속성 값이 같다면 같은 객체로 취급한다. 
      값 동등성과 동일성의 차이 
      - 동일성 비교는 참조값을 비교하기 때문에 속성과 타입이 같아도 참조값이 다르면 다른 객체로 구분한다.  == 연산자로 값을 비교
      - 동등성 비교는 equals() 함수를 통해 객체의 속성을 비교한다. Object의 equals() 메서드로 값을 비교 
    • 데이터의 무결성을 보장하며, 자가 유효성 검사를 통해 데이터를 검증한다. 
      자가 유효성 검사(self validation) : 객체가 생성될 때 자체적으로 데이터의 유효성을 검사하고, 유효하지 않은 데이터가 발생한 경우 예외를 발생하여 VO 객체는 안전하게 데이터를 관리하고 데이터의 일관성을 유지한다. 
    • 주로 도메인 모델에서 사용되며, 비즈니스 도메인의 값을 나타냅니다

 

예시코드 

public class AmountVO {
    private final double value;

    public AmountVO(double value) {
        // 자가 유효성 검사: 금액은 음수가 될 수 없음
        if (value < 0) {
            throw new IllegalArgumentException("금액은 음수일 수 없습니다.");
        }
        this.value = value;
    }

    public double getValue() {
        return value;
    }

    // 다른 비즈니스 규칙을 적용할 수 있는 메서드 추가 가능
}

 

 

Entity vs DTO vs VO 의 차이를 간다히 정리하자면...

종류 역할
Entity 데이터베이스와의 상호작용
DTO 데이터 전송
VO 값을 나타내고 데이터 불변성을 유지