Spring Framework를 사용해 개발을 하다 보면 자주 등장하는 개념이 Entity
, DAO
, DTO
이다. 이번에는 이러한 용어들이 무엇이며 스프링에서 왜 자주 등장되고 사용되는지 알아보았다.
Entity란 DB의 테이블에 존재하는 Column들을 필드로 가지는 객체를 말한다.
Entity는 DB의 테이블과 1대 1로 대응되며, 때문에 테이블이 가지지 않는 컬럼을 필드로 가져서는 안된다. 또한 Entity 클래스는 다른 클래스를 상속받거나 인터페이스의 구현체여서는 안된다.
DAO는 Data Access Object의 약자로, 실제로 DB에 접근하는 객체를 말한다.
DAO는 Service 단과 데이터베이스를 연결하는 역할을 하며, JPA에서는 DB에 데이터를 CRUD 하는 Repository 객체들이 DAO라고 볼 수 있다.
DAO는 데이터베이스에 접근하기 위한 로직과 목표하는 비즈니스를 처리하기 위한 로직을 분리시키기 위해 사용한다.
DTO는 Data Transfer Object의 약자로, 계층 간에 데이터를 교환해주는 역할을 하며 DB에서 꺼낸 데이터를 저장하는 Entity를 가지고 만드는 일종의 Wrapper라고 볼 수 있다.
Entity를 Controller 같은 클라이언트단과 직접 마주하는 계층에 직접 전달하는 대신 DTO를 사용해 데이터를 교환한다. DTO는 그저 계층간 데이터 교환이 이루어 질 수 있도록 하는 객체이기 때문에, 특별한 로직을 가지지 않는 순수한 데이터 객체여야 한다. 또한 DB에서 꺼낸 값을 DTO에서 임의로 조작하여 데이터의 변경을 막고자 DTO에서는 Setter를 만들지 않고 생성자에서 값을 할당한다.
DTO는 도메인 모델을 캡슐화하여 보호할 수 있다는 점에서 사용 가치를 갖는다.
평소에 개발을 할 때는 DB에서 데이터를 꺼내와 하나의 DTO를 통해 service 단과 controller 단을 거쳐 클라이언트로 보내줬었다. 하지만 스터디를 하면서 이러한 방식이 서비스와 컨트롤러 단의 의존성을 강화해 결합을 강화시킨다는 사실을 깨닫게 되었다. 모듈간의 의존성을 낮추기 위해 service와 controller 단을 나누어 놓았는데 정작 데이터를 주고 받을 때에는 하나의 DTO를 사용하면서 결합을 강화시키고 있었다. 따라서 DTO를 사용할 때에는 service와 controller 각각의 DTO를 따로 만들어 사용해야 한다.
* Entity와 DTO를 분리하는 이유
도메인 설계가 아무리 잘 되었다 해도 Getter만을 이용해서 원하는 데이터를 표시하기 어려운 경우가 발생할 수 있는데, 이 경우에 Entity와 DTO가 분리되어 있지 않다면 Entity 안에 Presentation을 위한 필드나 로직이 추가되게 되어 객체 설계를 망가뜨리게 된다. 때문에 이런 경우에는 분리한 DTO에 Presentation 로직을 추가해서 사용하고, Entity에는 추가하지 않아서 도메인 모델링을 깨뜨리지 않는다.