개요
회의에 들어가면 저를 포함해서 DAO와 Repository, DTO와 VO를 혼용해서 사용하는 사람들이 많습니다.
이번 기회에 위 용어들의 개념을 정리하면서 차이점을 명확하게 짚고 가고자 합니다.
* 출처에 남긴 블로그 및 유튜브를 많이 참고했습니다. 보다 자세한 내용은 출처를 확인해 주시면 감사하겠습니다!
Entity
- DB 테이블을 표현하는 객체 (실제 DB와 매핑되는 객체)
- DB 테이블 내 모든 칼럼을 필드로 갖는 클래스로 비즈니스 로직을 갖는 메서드를 선언 가능
- 엔티티의 가장 큰 특징은 식별자를 가진다는 것
- 식별자 외 필드 데이터가 변경된다고 하더라도 식별자는 동일하기 때문에 해당 객체가 다른 객체가 되는 것은 아님
- 후술 하겠지만 VO와 Entity의 차이점은 Entity의 경우 식별자가 있지만 VO는 식별자가 없음
VO (Value Object)
- 값 자체를 표현하는 불변 객체 (Setter 메서드를 포함하지 않고 생성자를 통해서만 값 세팅)
- DTO와 달리 비즈니스 로직을 갖는 메서드 선언 가능
- 속성값이 모두 같을 경우 같은 객체
- 통상적으로 MyBatis와 같이 SQLMapper를 사용할 때 VO 객체를 선언하고 Jpa와 같이 ORM을 사용할 때 Entity 객체를 선언
- ORM은 SQL문이 아닌 RDB 객체를 자바 객체로 매핑 (식별자를 가짐)
- SQLMapper는 SQL문으로 RDB에 접근하고 데이터를 객체에 매핑하기 때문에 객체 간 관계나 식별자를 가질 수 없음
- 위와 같은 이유로 Jpa에서는 식별자를 가지는 Entity, MyBatis에서는 값 객체를 의미하는 VO라는 명칭 사용
DTO (Data Transfer Object)
- "계층 간" 데이터를 전달하기 위해 사용하는 객체
- ex) Web Layer와 Service Layer 간 전달하기 위한 객체
- Getter/Setter 메서드만을 갖고 별도 로직을 갖지 않음 (순수하게 데이터 전달용)
- Setter 메서드를 제거하고 생성자를 통해서만 값을 세팅하게끔 변경할 경우 DTO가 불변객체가 되어 보다 안정적
- VO와 달리 속성값이 모두 같다고 해서 같은 객체라고 할 수 없음
Api 요청이나 응답 값을 전달하는 클래스로 Entity가 아닌 DTO를 사용해야 하는 이유
- View Layer는 변경이 잦은 Layer인데 View Layer를 변경할 때마다 Entity를 변경할 경우 서비스에 끼치는 영향도가 너무 커지기 때문에 요청이나 응답 값으로 다른 클래스에 영향을 끼치지 않고 자유롭게 변경 가능한 DTO를 사용하도록 권장
- REST Api일 경우에도 Api 규격서가 존재하는데도 불구하고 테이블 변경 사항이 생길 때마다 Api 규격이 변경되기 때문에 요청/응답 값을 Entity가 아닌 DTO 사용 권장
VO와 DTO의 차이 정리
DTO | VO | |
용도 | 레이어 간 데이터를 전달하기 위해 선언 | 값 자체를 표현하기 위해 선언 |
동등 결정 | 속성값이 모두 같더라도 객체가 같음을 보장하지 않음 | 속성값이 모두 같으면 같은 객체 |
가변 / 불변 | setter 존재 시 가변 setter 존재하지 않을 경우 불변 |
불변 |
로직 유무 | getter/setter 외 별도 로직 X | getter/setter 외 별도 로직 O |
VO와 DTO를 혼용하는 케이스가 많은 이유
- Core J2EE PATTERNS 책에서 데이터 전달용 객체를 1판에서는 VO, 2판에서는 TO로 정의함에 따라 혼용하는 사례가 많은 것으로 추정
DAO (Data Access Object)
- DAO는 데이터 지속성을 추상화한 개념으로 Repsitory와 비교하자면 DataSource에 가까운 보다 하위 개념
- DAO는 쿼리를 숨기는 데이터 매핑 및 액세스 계층
- DAO가 Repository보다 하위 개념이기 때문에 DAO에서는 Repository를 사용할 수 없지만 Repository에서는 기본 스토리지에 접근하기 위해 DAO를 사용 가능
- Repository 내 다수의 DAO 사용 가능
- 도메인 객체들 내 비즈니스 로직이 거의 없을 경우 DAO와 Repository를 혼용해서 사용하지만 엄연히 다른 개념
- 하지만, 김영한 강사님 말씀에 따르면 개념의 차이만 있을 뿐 실제로 개발할 때는 비슷하게 사용된다고 합니다.
- https://www.inflearn.com/questions/111159/domain%EA%B3%BC-repository-%EC%A7%88%EB%AC%B8
Repository
- Repository는 도메인 객체에 가까운 보다 상위 개념
- Repository는 도메인과 데이터 액세스 레이어 사이의 계층으로 데이터를 수집하고 도메인 개체를 세팅하는 복잡성을 숨김
- 앞서 설명했듯이 Repository는 기본 스토리지에 접근하기 위해 DAO 사용 가능
Repository와 DAO 차이 정리
Repository | DAO | |
추상화하는 대상 | 객체 컬렉션의 추상화 | 데이터 지속성의 추상화 |
개념 | 도메인 객체에 가까운 보다 상위 개념 | DataSource에 가까운 보다 하위 개념 |
계층 (Layer) | 도메인과 데이터 엑세스 계층 사이에서 데이터를 수집하고 도메인 개체를 세팅하는 복잡성을 숨기는 레이어 | 쿼리를 숨기는 데이터 매핑 및 데이터 엑세스 레이어 |
사용 가능 유무 | 한 개 이상의 DAO 사용 가능 | Repository 사용 불가능 |
Repository와 DAO 예시 코드 (출처: baeldung)
Mapper
- MyBatis와 같은 SQLMapper를 사용할 때 정의해 놓은 SQL과 개발할 때 사용하는 메서드를 연결하고 결과 값을 정의해 놓은 타입으로 매핑시켜 주는 인터페이스
- 실제 쿼리는 xml 내 작성
- Repository는 Mapper를 포함하는 개념으로
- Mapper는 SQL을 메서드랑 단순 매핑하는 역할
- Repository는 DB를 조회 및 조작하는 것을 비즈니스 로직과 분리하기 위해 존재하는 레이어
- 물론 경우의 따라 Service에서 Repository를 거쳐 Mapper를 호출하는 구조가 아니라 Service에서 Mapper를 직접 호출하는 케이스도 존재할 수 있으며 아래와 같은 케이스 모두 존재할 수 있으며 단순 구조만을 보고 옳고 그름을 판단할 수 없음
- Controller -> Service -> Repository -> Mapper -> mapper.xml
- Controller -> Service -> Mapper -> mapper.xml
정리
위 내용을 하나의 그림으로 정리해봤습니다.
출처
https://www.youtube.com/watch?v=z5fUkck_RZM
https://sons6488.tistory.com/10
https://devlopsquare.tistory.com/106
https://www.baeldung.com/java-dao-vs-repository
https://velog.io/@ygreenb/DTO-VO-Entity
https://www.inflearn.com/questions/111159/domain%EA%B3%BC-repository-%EC%A7%88%EB%AC%B8
https://pamyferret.tistory.com/69
반응형
'DB > 개념 정리' 카테고리의 다른 글
[DB] 트랜잭션과 DB Lock 정리 (0) | 2023.03.20 |
---|---|
[DB] Connection Pool 정리 (0) | 2023.03.20 |
[DB] JDBC 정리 (2) | 2023.03.17 |