Back-end/Spring

[Spring] DTO와 VO

woojeans7 2025. 6. 17. 16:48

📚 DTO와 VO(Data Transfer Object and Value Object)

데이터를 입력 받아서 전달하고, 값을 처리하는 과정에 DTO, VO 라는 개념이 필요하다.

쉽게 말해서 VO 는 값 그 자체로 입력 받은 값을 저장하는 객체이며, DTOVO를 불러오고 전달하기 위해서 사용하는 그릇이라고 보면 된다.


DTO

DTO (Data Transfer Object) : 데이터 전송 객체로, 프로세스 간에 데이터를 전달하는 객체

말그대로 데이터를 전달하기 위해서 사용하며, 데이터를 담는 그릇이나 상자라고 생각하면 쉽다.

서버와 클라이언트가 데이터를 주고 받을 때 사용하는 데이터 묶음이다.

 

DTO는 데이터 전달 뿐만 아니라, View에 필요한 데이터만 포함시켜서 사용할 수 있다.

id, 생성시각과 같이 클라이언트에 굳이 필요없는 정보는 제외하고 전달할 수 있다.

Controller, Service, API 응답 등에서 사용하고, Setter를 사용한 가변객체로 사용할 수 있다.

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class BoardDTO {
    private String title;
    private String content;
    private String writer;
}

VO

VO(Value Object) : DB와 1:1 매핑되는 객체로, 실제 데이터를 담고 있는 실체.

주로 DAO 또는 Entity 클래스와 함께 사용됨.

 

VO 는 불변객체로 생성된 후에는 값을 변경할 수 없다. 그래서 Setter를 사용할 수 없고, 동일 값이면 동일 객체로 취급할 수 있다.

DAO, Repository, 도메인 내부에서 사용하고, DB컬럼을 모두 포함한다.

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class BoardVO {
    private Long no;
    private String title;
    private String content;
    private String writer;
    private Date regDate;
    private Date updateDate;
}

DTO ↔ VO 변환

VO 에는 보안에도 민감한 값들도 다 들어갈 수 있기 때문에 데이터를 전달하고, 전달받는 과정에서는 DTO로 변환이 필요하다.

또한 필요한 정보만을 선택해서 전달하기에는 DTO 로 변환하는 것이 유연하게 개발할 수 있다.

즉, DTOVO를 변환하는 이유는, 목적이 다르기 때문에 서로 분리하고 연결해주는 ‘중간다리’가 필요하기 때문이다.

// DTO 안에 사용한 메서드
public static BoardDTO of(BoardVO vo) {
        return vo == null ? null : BoardDTO.builder()
                  .no(vo.getNo())
                  .title(vo.getTitle())
                  .content(vo.getContent())
                  .writer(vo.getWriter())
                  .regDate(vo.getRegDate())
                  .updateDate(vo.getUpdateDate())
                  .build();
}

// DTO -> VO 변환
public BoardVO toVo() {
        return BoardVO.builder()
                                  .no(no)
                  .title(title)
                  .content(content)
                  .writer(writer)
                  .regDate(regDate)
                  .updateDate(updateDate)
                  .build();
}

요약

비교 항목 DTO VO
역할 데이터 전달 실제 데이터 보관
위치 Controller, Service DAO, Entity, DB 연결
포함 필드 사용자 입력값 DB 컬럼 전부
변형 가능 가능 (setter) 가능 또는 불변
예시 BoardDTO, LoginDTO BoardVO, UserVO