Back_End/JAVA

자바(JAVA) DAO, DTO, VO 란?

10Biliion 2025. 2. 26. 13:39

 

 

 

1. DAO, DTO, VO란?

1.1 DAO (Data Access Object)

DAO는 데이터베이스와 직접적으로 상호작용하는 객체로, 데이터베이스의 CRUD(Create, Read, Update, Delete) 작업을 수행합니다. DAO는 주로 SQL 쿼리를 실행하고 결과를 반환하는 역할을 합니다.

특징:

  • 데이터베이스와 직접적인 연결을 담당
  • SQL을 실행하여 데이터를 조회하거나 저장
  • 서비스 레이어에서 호출되어 데이터를 주고받음
  • 일반적으로 인터페이스와 구현 클래스로 분리하여 사용

DAO 예제 (Spring Boot + MyBatis)

@Mapper
public interface UserDAO {
    @Select("SELECT * FROM users WHERE id = #{id}")
    UserVO getUserById(int id);

    @Insert("INSERT INTO users(name, email) VALUES(#{name}, #{email})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    void insertUser(UserVO user);
}

1.2 DTO (Data Transfer Object)

DTO는 계층 간 데이터 전송을 위한 객체로, 보통 컨트롤러에서 서비스 레이어로 데이터를 전달할 때 사용됩니다. DTO는 비즈니스 로직을 가지지 않으며, 단순히 데이터를 담는 용도로 사용됩니다.

특징:

  • 계층 간 데이터 전달 목적
  • 일반적으로 getter, setter 또는 빌더 패턴을 활용
  • JSON 직렬화/역직렬화에 적합
  • 불필요한 데이터를 제거하여 필요한 데이터만 전송
public class UserDTO {
    private String name;
    private String email;

    public UserDTO() {}

    public UserDTO(String name, String email) {
        this.name = name;
        this.email = email;
    }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }

    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
}

 

컨트롤러에서 DTO를 사용하는 예제

@RestController
@RequestMapping("/users")
public class UserController {
    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PostMapping("/create")
    public ResponseEntity<String> createUser(@RequestBody UserDTO userDTO) {
        userService.createUser(userDTO);
        return ResponseEntity.ok("User created successfully");
    }
}

1.3 VO (Value Object)

VO는 특정 도메인 내에서 변하지 않는(Immutable) 데이터를 표현하는 객체입니다. DTO와 달리 불변성을 유지하며, 객체의 값이 한 번 설정되면 변경되지 않습니다.

특징:

  • 읽기 전용(Immutable) 객체로 사용
  • 값 기반 비교(equals(), hashCode() 재정의 필요)
  • 주로 DB에서 조회한 값을 담는 용도로 사용됨
public class UserVO {
    private final int id;
    private final String name;
    private final String email;

    public UserVO(int id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }

    public int getId() { return id; }
    public String getName() { return name; }
    public String getEmail() { return email; }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UserVO userVO = (UserVO) o;
        return id == userVO.id && Objects.equals(name, userVO.name) && Objects.equals(email, userVO.email);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, email);
    }
}

2. DAO, DTO, VO의 차이점

 

구분 DAO DTO VO
역할 데이터베이스와 직접 연결하여 데이터를 CRUD 수행 데이터를 계층 간 전송할 때 사용 불변 객체로 데이터를 보관하는 용도
변할 수 있는가? 변경 가능 (데이터베이스 변경 가능) 변경 가능 (getter, setter 제공) 변경 불가능 (Immutable)
주요 용도 데이터베이스 접근 API 또는 서비스 계층 간 데이터 전송 읽기 전용 도메인 객체

3. DAO, DTO, VO를 함께 사용

@Service
public class UserService {
    private final UserDAO userDAO;

    public UserService(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    public void createUser(UserDTO userDTO) {
        UserVO userVO = new UserVO(0, userDTO.getName(), userDTO.getEmail());
        userDAO.insertUser(userVO);
    }

    public UserDTO getUserById(int id) {
        UserVO userVO = userDAO.getUserById(id);
        return new UserDTO(userVO.getName(), userVO.getEmail());
    }
}

실행 흐름

  1. 클라이언트가 POST /users/create 요청을 보냄 (JSON 데이터 포함)
  2. UserController에서 DTO로 데이터를 받고 UserService로 전달
  3. UserService는 DTO를 VO로 변환한 후 UserDAO를 호출하여 DB에 저장
  4. DB에서 조회할 때는 UserDAO가 VO를 반환하고, UserService가 이를 DTO로 변환하여 컨트롤러에 전달

 

  • DAO: 데이터베이스와 직접 연결하여 CRUD 수행
  • DTO: 데이터 전송을 위한 객체 (계층 간 이동)
  • VO: 불변 객체로, 읽기 전용 데이터를 표현할 때 사용