Backend/spring (Boot)

DTO / VO / DAO / Entity / Model 비교

dddzr 2026. 1. 25. 12:02

DTO / VO / DAO / Entity / Model은 모두 Spring에서 데이터와 관련된 객체들로, 각기 다른 역할을 한다. 헷갈리는 개념들을 한 번에 정리해보자! 😎

📌🔥1. DTO / VO / DAO / Entity / Model 비교

구분 역할/목적 특징 사용하는 층(Layer) 변경 가능성 예시
VO 값 객체 (Value Object) 불변 객체 (immutable) DTO, Entity와 연동 가능 변경 X Money, Point, Address
DTO 데이터 전달 객체 (Data Transfer Object) 계층 간 데이터 전달용 Controller ↔ Service ↔ DAO 변경 O UserDTO, LoginDTO
DAO DB 접근 객체 (Data Access Object) DB 호출/쿼리 수행 Repository Layer 변경 O UserDao, OrderDao
Entity 실제 DB 테이블과 매핑되는 객체 JPA 사용 시 @Entity DB ↔ Application 변경 O User, Product
Model View에 넘겨주는 데이터 묶음 (MVC용) UI에 최적화 Controller ↔ View 변경 O Model.addAttribute("user", user)

➡️ DTO는 계층 간 데이터 전달, VO는 값 객체, DAO는 DB 접근, Entity는 DB 테이블과 매핑, Model은 View에 데이터를 전달하는 역할을 한다.


📌 2. 각 객체 개념 상세 설명

VO (Value Object)

  • 값 자체가 중요한 객체 (예: Address, Money, Coordinate)
  • 일반적으로 불변 객체로 설계 (getter만 있고 setter 없음)
  • 값 세팅은 객체가 생성될 때 생성자(constructor)에서함. (예: AddressVO address = new AddressVO("서울", "테헤란로");)
  • equals(), hashCode() 오버라이딩해서 값 비교 중심
  • 주로 DDD(도메인 주도 설계)에서 많이 등장함
  • JPA에서 @Embeddable로 쓰이기도 함

📖 예시

public class AddressVO {
    private final String city;
    private final String street;

// 생성자 + getter만 있음
    public AddressVO(String city, String street) {
        this.city = city;
        this.street = street;
    }

    public String getCity() { return city; }
    public String getStreet() { return street; }

    // equals / hashCode override
}




DTO (Data Transfer Object)

  • 계층 간 데이터를 전달하기 위한 객체
  • 일반적으로 getter/setter 다 있음
  • Controller ↔ Service ↔ DAO(Repository) 간에 데이터를 넘기기 위해 사용
  • 가공된 데이터나 UI에 맞는 구조로 만들어짐
  • 네트워크 전송, API 요청/응답 등에 사용됨
  • Validation용 어노테이션 붙기도 함 (@NotNull, @Size 등)

📖 예:

public class UserDTO {
    private String username;
    private String email;
    
    // getter / setter
}

 


DAO (Data Access Object)

  • DB와 직접 통신하는 역할 (CRUD 수행)
  • SQL 또는 MyBatis, JPA 등으로 실제 DB 쿼리 실행
  • 보통 interface + 구현체 (UserDao, UserDaoImpl)
  • 내부에서 DTO나 VO를 주고받음
  • 주로 @Repository or @Mapper 붙음

📖 예:

@Repository
public interface UserDao {
    User findById(String id);
}

// or

@Mapper
public interface UserMapper {
    User selectUserById(String id);
}

 

🔹 @Repository@Mapper는  DAO 역할 인터페이스, 사용하는 프레임워크에 따라 다름

  • @Repository → 스프링 일반 컴포넌트 등록 (MyBatis에서도 사용 가능)
  • @Mapper → MyBatis에서 자동으로 Mapper Proxy를 등록해주는 전용 애노테이션

Spring Boot에서는 @Mapper를 자주 사용, Spring에서는 @Repository + MapperScannerConfigurer 조합도 흔함


Entity

  • DB 테이블과 매핑되는 객체 (ORM 용도)
  • JPA, Hibernate에서 @Entity로 사용됨
  • 데이터 변경 감지를 위해 setter 있음
  • 비즈니스 로직 포함하기도 함

📖 예:

@Entity
public class User {
    @Id
    private Long id;
    private String name;
}

 


Model (Spring MVC)

  • View(ViewResolver, JSP 등)에 데이터를 넘기기 위한 객체
  • 컨트롤러에서 View로 데이터 전달 시 사용
  • Model.addAttribute("key", value) 식으로 전달

📖 예:

@GetMapping("/user")
public String userDetail(Model model) {
    model.addAttribute("user", userDTO);
    return "userPage";
}

 


📌 3. 정리 그림 (흐름)

[Client] 

   ⬇

[Controller] → View (Model)

   ⬇ (DTO 사용)

[Service]

   ⬇ (Entity, VO 사용)

[DAO/Repository] ⬅→ DB (Entity 매핑)