Q. 보통 DB에 여러데이터들이 존재할 때 DTO를 통해 일부만 가져오는 것도 좋지만 정규화하여 잘 분리하면 결국 DB의 전체값을 활용하게 되는 것 아니야? 바꿔 이야기하면 DTO를 사용해 일부만 가져오는 건 이해했어. 그렇데 데이터를 넣을때 보통 DB에 null을 지양하게 되는데 set을 사용할 때 null 값을 넣도록 설계하지는 않을것 같거든. 결국 get, 즉 데이터를 분리해서 가져오기 위해 DTO가 필요한 셈이야?
A. 맞습니다. DTO의 사용은 다양한 상황에 따라 결정되며, 일부만 가져오기 위한 것 뿐만 아니라 다른 목적으로도 활용될 수 있습니다. 여러 가지 상황에서 DTO를 사용하는 몇 가지 이유는 다음과 같습니다:
DTO는 주로 데이터 전송과 관련된 다양한 요구 사항을 해결하기 위해 사용되며, 데이터를 일부만 가져오는 것 외에도 데이터를 가공하거나 필터링하는 등의 다양한 용도로 활용될 수 있습니다.
우리가 작성한 Question, Answer 클래스는 엔티티(Entity) 클래스이다. 엔티티 클래스는 데이터베이스와 직접 맞닿아 있는 클래스이기 때문에 컨트롤러나 타임리프 같은 템플릿 엔진에 전달하여 사용하는 것은 좋지 않다. 컨트롤러나 타임리프에서 사용하는 데이터 객체는 속성을 변경하여 비즈니스적인 요구를 처리해야 하는 경우가 많은데 엔티티를 직접 사용하여 속성을 변경한다면 테이블 컬럼이 변경되어 엉망이 될수도 있기 때문이다.
이러한 이유로 Question, Answer 같은 엔티티 클래스는 컨트롤러에서 사용할수 없게끔 설계하는 것이 좋다. 그러기 위해서는 Question, Answer 대신 사용할 DTO(Data Transfer Object) 클래스가 필요하다. 그리고 Question, Answer 등의 엔티티 객체를 DTO 객체로 변환하는 작업도 필요하다. 그러면 엔티티 객체를 DTO 객체로 변환하는 일은 어디서 처리해야 할까? 그렇다. 바로 서비스이다. 서비스는 컨트롤러와 리포지터리의 중간자적인 입장에서 엔티티 객체와 DTO 객체를 서로 변환하여 양방향에 전달하는 역할을 한다.
View에서 DB Entity 클래스를 직접 객체로 사용하면 민감한 정보등도 함께 다루게 된다. (회원의 개인정보, 비밀번호), 즉 View에서 사용하는 객체 자체를 DTO를 이용해 필요한 정보만 담아서 사용하는 것이 좋다.
분산된 DB로부터 필요한 값을 가져와서 사용하기 위하여. 즉 상세페이지라는 View에서 3개의 DB를 다룬다고 할 때 3개의 DB를 사용하되 모든 값을 다 다루는 객체를 사용하는 것이 아니라 필요한 값만 저장되는 DTO를 사용하고 이 DTO 객체를 Model에 저장한다.
그런데 문제는.. 예제들을 보면 DTO에서도 Entity의 Setter 메서드를 사용한다는 것이다. 사실 DB에 데이터를 저장하는 행위는 JPA의 Repository(=DAO)의 save 기능으로도 충분한데... 결국 Entity의 클래스의 데이터형을 먼저 갖추고 save에 넣어줘야 하기 때문에 Entity에서 Setter 메서드를 없에는 건 불가능한 건가?
가능하다. @Builder 애노테이션을 사용해 생성자로 더티 체크, 또는 JPA의 메서드를 이용해 데이터의 CRUD가 가능하다.