ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] DAO / DTO / VO 정리
    Spring 2022. 10. 5. 01:31

     

     

    처음 스프링을 접하게 되면 가장 헷갈리는 개념 중 하나가 DAO, DTO, VO가 아닐까 생각이 듭니다.

    제가 프로젝트를 했을 당시에도 이 개념이 헷갈리시는 분들이 많아서 긴 시간을 들여 설명 했던 기억이 납니다.

    그래서 블로그에도 이 개념들을 간단하면서도 명료하게 정리해 두려고 합니다.

     


    DTO란?

     

    먼저 DTO입니다. 줄임말을 풀어쓰는 순간 이해가 훨씬 쉽습니다.

     

    DTO는 Data Transfer Object입니다.

    "데이터 전송 객체" 라는 뜻입니다.

     

    클라이언트에서 서버로 데이터를 전송할 때, 이 DTO 객체에 필드들을 매핑하여 전달합니다.

    필드의 이름과 타입만 맞춘다면 디스패쳐 서블릿이 자동으로 데이터들을 이 DTO객체에 매핑해서 전달합니다.

    그리고 각 계층간 데이터를 전송할 때에도 사용합니다.

     

    Spring은 POJO(Plain-Java-Object)기반이기 때문에 이 DTO클래스 또한 POJO로 작성합니다. 롬복을 사용할 경우 @Data 어노테이션으로 DTO객체를 빠르게 생성할 수 있습니다.

     

    그렇다면 이 DTO객체의 구성요소엔 어떤 것들이 있을까요?

     

    롬복의 @Data 어노테이션의 설명입니다. 사진의 @ToString 이후부터는 DTO객체의 필수사항은 아닙니다.

    DTO의 구성요소
    (1) Getter
    (2) Setter
    (3) RequiredArgsConstructor

    (1) Getter / Setter

     

    DTO클래스는 POJO임과 동시에 자바빈즈 클래스 규약을 따릅니다. 따라서 모든 필드들은 private하게 작성해야 하고, 대신 게터와 세터를 통해 필드에 값을 세팅하고, 얻어올 수 있습니다.

     

    (2) RequiredArgsConstructor

     

    이 어노테이션은 초기화되지 않은 final필드, @NonNull이 붙은 필드에 대한 생성자를 생성합니다. 둘다 없을경우 @NoArgsConstructor와 같이 매개변수 없는 기본 생성자가 만들어집니다.

     


    VO란?

     

    VO는 Value Object, "값 객체"라는 뜻입니다.

     

    DTO가 데이터를 전송하기 위한 객체였다면 VO는 값 그자체를 가지고 있는 객체입니다.

    롬복에서는 @Value 어노테이션으로 VO객체를 빠르게 만들 수 있도록 제공합니다.

     

     

    VO 역시 자바빈즈 클래스로 작성합니다.

    VO의 구성요소
    (1) Getter
    (2) AllArgsConstructor

     

    VO는 매핑된 이후에는 값을 변경하는 것을 허용하지 않습니다, 즉 불변입니다. 따라서 setter가 없고, getter만 존재합니다.

    값을 초기화할 때에는 AllArgsConstructor, 즉 모든 필드를 매개변수로 가지는 생성자가 있고, 그 생성자를 통해서만 초기화 할 수 있습니다. 따라서 처음 VO가 생성될 때 값이 저장되고, 이후 데이터의 변경이 불가능합니다.

     

    마이바티스와 같은 프레임워크들은 데이터베이스의 쿼리문 수행 결과를 VO로 지정하면, 자동으로 값을 매핑하여 전달해줍니다.

     


    DTO와 VO, 언제 사용할까?

     

    그렇다면 DTO와 VO는 언제 사용할까요?

    여러 자료들을 찾아본 결과 DTO와 VO의 차이는 분명히 있지만, 그걸 엄격하게 구분해서 사용할 필요는 없다는 의견이 대부분입니다. 그러나 협업을 할 때에 DTO와 VO의 용도를 확실히 구분했다면, 그 용도에 따르는 것이 좋다고 생각합니다.

     

    제가 협업을 했을 때에는 클라이언트 -> DB로 데이터를 전송할 때에는 DTO를 사용하고, DB에서 반환되는 데이터 타입은 VO를 사용하기로 약속했습니다.

     

    이 규약에 따르면 둘의 방향이 완전하게 구분됩니다.

     

    이렇게 하면 DB의 조회 결과가 내부에서 임의로 변경될 위험이 없다는 점과, 용도의 구분히 확실하다는 장점이 있습니다.

     

     

    +) VO를 사용할 때의 주의점

     

    VO는 setter가 없고, 생성자를 통해서만 값을 초기화할 수 있습니다.

    그래서 SQL 실행결과를 VO에 매핑할 때에는 반드시 SELECT한 컬럼의 순서와 갯수, 타입을 VO와 맞춰주어야 합니다.

     

    DTO의 경우 setter로 값을 매핑하기 때문에 순서와 갯수가 일치하지 않아도 해당하는 필드명을 찾기 때문에 지키지 않아도 됩니다. 비어있는 필드는 null로 세팅됩니다.

     

    그러나 생성자는 그렇지 못하기 때문에 만약 순서나 갯수가 다르다면 그대로 예외를 발생시킵니다.

     


    DAO란?

     

    DAO는 Data Access Object, "데이터 접근 객체" 입니다.

     

    웹 계층 중 Business Layer(Service Layer)와 데이터베이스를 연결하는 연결고리 역할을 합니다.

     

    JDBC, MyBatis, JPA 등 persistence framework를 사용하여 데이터베이스와 연결을 할 때, 실제로 연결을 해주는 역할을 합니다. 각 프레임워크들의 동작방식은 약간씩 다르지만

    Connection Pool을 생성하고 -> SQL 쿼리문을 실행하고 -> 결과를 반환하는 이 과정을 수행합니다.

     

    마이바티스를 예로들면, 마이바티스는 DAO 인터페이스를 만들고, 구현 클래스를 만듭니다.

    구현 클래스에는 마이바티스의 xml파일에 등록된 네임스페이스 + "." + ID를 통해 작성해둔 SQL쿼리를 실행할 수 있습니다.

    (* 마이바티스의 경우엔 3이 나오면서 DAO를 사용하지 않고, DAO의 역할을 자동으로 수행해주는 매퍼 인터페이스 방식을 사용합니다.)

    댓글

Designed by Tistory.