TIL - #26 DTO, DAO, VO에 대해 정리하자

Quann·2023년 1월 28일
0

00. 개요

프로젝트를 진행하며 한 번쯤 마주치는 DTO
Data Transfer Object로, 계층간 데이터 전송을 위해 생성하는 객체이다.

그래서 항상 사용하는 DTO 에 대해 조사하다가,
DTO 외에도 DAO, VO 라는 Object 범위가 존재한다는 사실을 알고 이에 대해 공부했다.


01. 학습 내용

앞으로 서술할 DTO, DAO, VO 는 무슨 영문 약자인지만 알아도 충분한 의미 추론이 가능하다고 생각했다. 해당 개념에 대해 외우기보다는 느낌을 얻어가는 것이 중요한 것 같다.

01.01. DTO(Data Transfer Object)

직역하면 데이터 전송 객체로, 계층간 데이터 전송을 위해 만들어진 객체로 이해 가능하다.
예를들어, Reposiotry에서 Entity를 조회한 뒤, 해당 Entity를 Client에게 바로 뱉을 수는 없는 노릇이다.
보안성이나 클라이언트가 원하는 정보 같은 사항을 고려해 적절한 데이터를 전송해주어야 하기 때문이다.

따라서, 계층간 데이터를 이동할때는 클라이언트 코드에서 원하는 정보가 담긴 객체를 던져주어야 하는데, 이때 사용하는 것이 DTO 이다.

Post.java

@Entity
@Getter
@Table(name = "posts")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Post extends TimeStamp {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;

    @Lob
    private String content;

    @OnDelete(action = OnDeleteAction.CASCADE)
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    private User user;
}

PostSimpleResponseDto.java

@Getter
@AllArgsConstructor
public final class PostSimpleResponse {
    private final Long id;
    private final String nickname;
    private final String title;
    private final Long likeCount;
    private final LocalDateTime createdAt;
}

다음 두 객체를 보면 확인할 수 있다.

클라이언트에게 User에 대한 정보를 던져줄때, User 객체를 그대로 던져주게 된다면, User의 Password, name 등의 정보가 그대로 노출 될 것이다.
하지만, 이 정보를 Dto에 담아 반환하게 된다면, 적절한 정보만 뽑아서 사용자에게 노출시킬 수 있게 되는 것이다.

해당 예시는, Client와 Server간의 DTO 관점에서 서술했지만,
Controller, View, Business Layer, Persistence Layer 등의 다양한 계층간에 데이터 전송을 할때도 적용할 수 있는 개념이다.

01.02. DAO(Data Access Object)

직역하면 데이터 접근 객체이다.
즉, 데이터베이스의 데이터에 접근하기 위한 객체로, DB와 연결할 커넥션까지 물고있는 경우가 많다고 한다.
하지만, JPA, Mybatis 같은 라이브러리를 사용할 경우, 커넥션풀을 제공해주기 때문에 편리하게 사용 가능하므로, 추가적인 DAO의 생성은 하지 않는다고 한다.

만약 Post객체를 DB에 저장해야 한다는 상황이 있으면, 다음과 같이 작성이 가능하다.

PostDao.java

public class PostDao {

    public void add(PostRequestDto dto) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/testDb", "sa", "");

        PreparedStatement preparedStatement = connection.prepareStatement("insert into post(title,content, user_id) value(?,?,?)");

        preparedStatement.setString(1, dto.getTitle());
        preparedStatement.setString(2, dto.getContent());
        preparedStatement.setLong(3, dto.getUserId());
        preparedStatement.executeUpdate();
        preparedStatement.close();
        
        connection.close();
    }
}

예제 코드를 보면 쉽게 알 수 있다시피, 데이터베이스와의 커넥션부터 데이터베이스에 접근하기 위한 메서드까지 작성하여, DAO 객체를 통해 DB에 접근이 가능해지는 것이다.

01.03. VO(Value Object)

직역하면 값 객체로, 값의 표현을 위해 사용되는 객체이다.
자바의 경우 값 타입을 표현하기 위해 불변 클래스를 사용하는데, 이는 ReadOnly 특성을 가지고 있다.

위의 Post를 예시로 들면, Post 객체가 Status라는 정보가 필요하다는 예시를 들 수 있을 것 같다.
이때, Post 객체에 대한 Status 정보는 값만을 담고 있으며, 해당 정보는 Getter를 통한 ReadOnly 특성만을 가지고 있다. 따라서, Status 에 대한 변경이 이루어질 경우에는 해당 Status 에 대한 새로운 객체로 변경하여 사용하는 것이다.


02. 정리

아직까지는 DTO 밖에 사용하지 않았지만, VO 정도는 앞으로 다양한 부분에서 사용할 것 같다는 생각을 했다.

세가지 종류에 대한 개념을 정리하면서 어떻게 사용해야할지 고민하는 시간을 가졌다.


03. 오늘의 한 문단

영어를 알면 코딩이 쉬워진다.

profile
코드 중심보다는 느낀점과 생각, 흐름, 가치관을 중심으로 업로드합니다!

0개의 댓글