[JAVA] DAO, DTO, VO, Entity 개념 간단 정리

tech_bae·2025년 4월 2일

Java

목록 보기
10/10
post-thumbnail

웹 공부를하면서 자주 접하는 단어인 DAO, DTO, VO, Entity가 들을 때마다 헷갈려서 개념을 잡아 놓으려 정리하려 한다.

DAO

이름이 귀엽지 않은가
DAOData Access Object로 말 그대로 DB의 데이터에 접근하는 객체이다.

DAO의 주요역할은 아래와 같다.

  • 데이터베이스 연결 및 쿼리 실행
    SQL을 실행해서 데이터에 접근, 조회 및 조작.
  • 비즈니스 로직과 분리
    서비스 로직과 DB로직을 분리해서 보다 쉬운 유지보수를 가능케한다.
  • 객체와 관계형 DB사이의 매핑
    결과값을 객체로 변환하거나, 객체를 DB에 맞게 가공 및 저장한다.

Java Spring기준으로 DAO는 여러 모양새를 가지고 있을 수 있다.

  • DB Connection이 설정되어 있는 경우
  • 그렇지 않은 경우

MyBatis는 DB Connection정보를 root-context.xml이라는 파일에 저장하고
JPAapplication.yml(properties)에 설정하여 사용한다.


DTO

DTOData Transfer Object데이터를 전달하는 객체이다.
DTO는 Controller, View 등 레이어 사이에서 데이터를 전달하는 역할을 한다.

데이터를 전달하는게 역할을 가지는 객체이므로 서비스로직을 가지지 않는다.
데이터 전달 용도로 사용하는 객체이므로 당연히 서비스로직이 필요없다.

순수한 데이터객체로써 getter와 setter만 가진다.


public class DtoEx {
    private String name;
    private int age;

    DtoEx(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

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

    public void setAge(int age) {
        this.age = age;
    }
}

  • 롬복(Lombok)을 사용하여 가독성이 좋은 코드를 쓸 수 있다!
@Data   //Setter, Getter, toString
@Builder    //객체를 build 방식으로 생성할 수 있다.
@AllArgsConstructor //모든 필드 값을 매개변수로 받는 생성자
@NoArgsConstructor  //매개변수가 없는 생성자
public class DtoHasSetter {
    private String name;
    private int age;
}

VO

VOValue Object값 그 자체의 객체이다.
그냥 쉽게 Setter가 없는 DTO라고 보면 될 것 같다.(Getter만 존재 할 수 있다.)

즉 VO는 한 번 생성하면 변경이 불가하다(read-Only)
그렇기에 새로운 값을 사용하려면 새로운 VO를 생성해야한다.

또한 VO는 모든 필드값이 같으면 두 객체는 같다는 정의를 가진다.
이를 위해 equals()hashCode()의 오버라이딩이 필요하다.


@Getter
public class VoEx {
    private final String name;
    private final float height;

    public VoEx(String name, float height) {
        this.name = name;
        this.height = height;
    }


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


    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if(!(obj instanceof VoEx)) return false;
        VoEx o = (VoEx)obj;
        return Objects.equals(name, o.name) && height == o.height;
    }
}
public static void main(String[] args) {
        VoEx original = new VoEx("Max",182.2f);
        VoEx same = new VoEx("Max", 182.2f);

        boolean equals = original.equals(same);

        System.out.println(equals);
    }
    
// 출력 : true
// equals오버라이딩 안할 시 false가 출력된다)

Entity

Entity는 실제 DataBase의 테이블과 1:1 매핑되는 클래스이다.
고로 Entity는 DB 테이블의 존재하는 칼럼만을 필드로 가져야 한다.
테이블에 존재하지 않는 속성을 가져서도 안된다.

또한 Entity 기준으로 테이블이 형성되므로 Entity의 값이 바뀌면 DB에 반영된다.

Entity는 데이터를 전달하는 용도로 사용하면 안된다.
즉, DTO와 분리하여 사용하여야 한다.

추가로 Entity는 비즈니스 로직을 포함할 수도, setter() 메소드를 포함할 수도 있습니다.

@RequiredArgsConstructor
public class Order {
    private final int id;
    private final String customerId;
    private LocalDateTime orderDate;
    private int totalPrice;
    private Oder_Status status;
    
    //상태변경 비지니스 로직 가능
    public void setStatus(Oder_Status status) {
        this.status = status;
    }
    
    //id 기준으로 동일성 판단
    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Order order)) return false;
        return id == order.id;
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(id);
    }
}

마치며

공부하면서 자주 접하는 DAO, DTO, VO, Entity 개념을 그동안 다소 모호하게 알고 있었는데, 이번 글을 통해 가볍게나마 각 개념을 정리할 수 있었다.
단순히 개념을 읽고 이해하는 데 그치지 않고, 간단한 예제를 직접 만들어보며 코딩해 본 경험이 개념을 더 잘 체득하는 데 큰 도움이 되었다.

profile
전 아무고토 몰루고 아무고토 못해여

0개의 댓글