Repository와 DAO의 차이
Repository와 DAO의 차이
용어의 기원 관점에서의 차이
Repository?
- DDD에서 나온 용어
- 어디에 저장되는가/어디서 불러오는가를 추상화 하는 책임 을 지니고 있다.
- 즉, 각기 다른 DataSource(file, DB, redis, …)를 추상화(encapsulation) 하여 어디서 가져오든 신경쓰지 않도록 하는 역할.
DAO ( Data Access Object )
- traditional Java EE에서 나온 용어
- 이 역시 data access 메커니즘을 business logic과 분리(추상화)하기 위해서 나온 개념.
결국 최초 그 개념의 출발지점만 보면 repository와 dao는 별 차이가 없다. 그러나 요즈음에는 이 두 용어가 비슷하지만 다른 의미로 사용되고 있다. 각각의 용어와 개념을 차용한 라이브러리가 독자적으로 개발되고, 이 것이 전파되면서 용어의 분리가 일어난 것으로 보인다.
실무 관점에서의 차이
Repository
spring-data-*
를 통해서 Data Source와 입출력하는 인터페이스를 의미한다.- 1
@Entity
, 1 table에 대응된다. - 메서드 리턴값으로 DB Record(
@Entity
)를 반환한다.
DAO ( Data Access Object )
spring-data-*
를 사용하지 않는, persistence 추상화 컴포넌트.- 1 Domain Model(DTO)에 대응된다. (보통은)
- 메서드 리턴값으로 Domain Model | DTO를 반환한다.
- 메서드 내부에서 DB Record를 Domain Model로 가공하는 등 DB schema를 가리기 위한 추가적인 추상화가 들어간다.
- 여러 테이블을 조인한 쿼리를 작성해서 도메인 모델을 만들어야 하는 경우 REPOSITORY보다는 DAO에 어울림
- e.g., 2개의 table을 조인해서 하나의 domain model을 만들어 반환
- Domain Model
직원
에부서 이름
필드를 채워야 할 때,직원 join 부서 on 부서 번호
해서부서 이름
까지 한 번에 들고오고 싶은 경우.
- Domain Model
- e.g., 하나의 domain model을 2개 테이블에 나누어 저장 해야 하는 경우.
Spring에서 지원하는
@Repository
애너테이션은?
@Repository - javadoc 읽어보면 나와있다.
원래 DDD의 Repository에서 기반한 애너테이션이지만, traditional Java EE 패턴의 Dao에도 사용 할 수 있다. (단, DDD repository와 Dao의 차이에 대해서 이해하고 있어야 한다)
보통은 이렇게 Repository를 Dao로 확장해서 사용하게 된다.
- 한 시스템에서 Repository(1:1 매칭)와 DAO(join 해야되는 경우)는 모두 발생한다.
- 보통은
1 table > 1 @Entity > 1 Domain Model
이 되는 경우가 잦기 때문에, Repository를 Dao로 확장해서 사용하게 된다. - https://umbum.dev/1340
참고
- DAO와 REPOSITORY 논쟁 - 조영호님
- 도메인 레이어가 TRANSACTION SCRIPT 패턴으로 구성되고 퍼시스턴스 레이어에 대한 FACADE의 역할을 하는 객체가 추가될 때는 거리낌 없이 DAO라 부른다.
- 도메인 레이어가 DOMAIN MODEL 패턴으로 구성되고 도메인 레이어 내에 객체 컬렉션에 대한 인터페이스가 필요한 경우에는 REPOSITORY라고 부른다.
- benelog - 엔티티 클래스 설계와 퍼시스턴스 프레임워크 - 정상혁님
- https://www.youtube.com/watch?v=cflK7FTGPlg
- DAO는 퍼시스턴스 레이어를 캡슐화
- DDD의 REPOSITORY는 도메인 레이어에 객체 지향적인 컬렉션 관리 인터페이스를 제공
- 네이티브쿼리를 쓰게되면 JPA 장점이 없다. 하지만 시스템의 어떤 부분에서는 분명 네이티브쿼리가 더 적합한 경우가 있다. 그래서 둘을 섞어 쓰게 된다.
- 성숙한 사용자는 이미 2가지 프로그래밍 모델을 섞어서 쓰고 있을 가능성이 높음
- CUD, 단순R : Entity, Repository, 쿼리 자동 생성 (e.g., JPA)
- 복잡한 R : 응답전용 DTO, + QueryDSL 등으로 개념적인 쿼리는 직접 작성 (e.g., Spring JDBC)
DAO 관련
You should design your DAO according to your application needs, not the layout of your database. Start of with one DAO, and if it becomes too large, then refactor it into multiple DAOs in a way that makes sense to your code.
The whole point of a DAO is to hide any database concepts (like tables) from your application. Your application should just view it as a service with some useful methods.
For example, if your application needs some user data that comes from both the Users table and the EmailAddresses table, your application code should not have to coordinate two DAOs - it should call one DAO method getUserDetails() and the DAO will hide the fact that multiple tables need to be called.
I am recommending the first of the options in your question, but I wouldn’t restrict yourself to the rule “one DAO per container class”.