DAO와 리포지토리 패턴의 차이점은 무엇입니까?


423

DAO (Data Access Objects)와 리포지토리 패턴의 차이점은 무엇입니까? Enterprise Java Beans (EJB3), Hibernate ORM을 인프라로 사용하고 DDD (Domain-Driven Design) 및 TDD (Test-Driven Development)를 설계 기술로 사용하여 애플리케이션을 개발 중입니다.

답변:


471

DAO데이터 지속성 의 추상화입니다 . 객체 컬렉션의
Repository 추상화입니다 .

DAO종종 테이블 중심 데이터베이스에 더 가깝게 간주됩니다.
Repository집합 루트에서만 다루는 도메인에 더 가까운 것으로 간주됩니다.

Repository의를 사용하여 구현할 DAO수는 있지만 그 반대의 경우는 없습니다.

또한 a Repository는 일반적으로 더 좁은 인터페이스입니다. 그것은으로, 단순히 개체의 컬렉션해야한다 Get(id), Find(ISpecification), Add(Entity).

와 같은 메소드 Update는에 적합 DAO하지만 a Repository를 사용 하지 않는 경우 Repository엔터티 변경은 대개 별도의 UnitOfWork에 의해 추적됩니다.

라는 구현을 참조하는 것이 일반적 보인다 Repository정말 더의 인 것을 DAO, 따라서 나는 그들 사이의 차이에 대한 혼란이 있다고 생각합니다.


26
글쎄, DAO 클래스가 문자 그대로 IRepository인터페이스를 구현하기를 원하지 않을 것 입니다. 저장소에서 구현에서 DAO를 사용하기를 원할 것입니다. DAO는 테이블 단위의 객체이지만 Repository는 거의 항상 하나의 엔티티를 빌드하기 위해 여러 DAO를 사용해야합니다. 그렇지 않은 경우 리포지토리와 엔터티가 단일 테이블에만 액세스하면 빈혈 도메인을 구축 할 가능성이 높습니다.
quentin-starin

29
.NET 세계에서 특히 "리포지토리"라는 용어는 본질적으로 DAO가 무엇인지 나타내는 데 사용됩니다. "DAO"는 더 많은 Java 용어입니다.
Wayne Molina

14
@Thurein DAO는 테이블 당이 아니며 패턴은 데이터에 대한 액세스를 추상화하는 것입니다-원하는대로 (테이블 당 또는 그룹 또는 모델별로) 구현할 수 있습니다. 권장되는 방법은 기본 지속성을 강력하게 고려하지 않고 항상 도메인 모델을 기반으로 DAO를 구성하는 것입니다. 사용하기 쉽고 명확하고 유지 방법에 약간의 유연성을 제공하기 때문입니다 (예 : 필요한 경우) 데이터를 XML 파일로 저장하거나 데이터베이스가 아닌 메시지 큐에서 가져 오는 DAO ...).
Stef

21
@Stef 나는 동의하지 않습니다. DAO는 정의 ( 데이터 액세스 개체) 로 데이터 를 반환 합니다 . 저장소는 정의에 따라 도메인 객체를 반환합니다. OOP에서는 다른 방식이 아닌 하나 이상의 데이터 오브젝트에서 도메인 오브젝트를 작성하기 때문에 저장소가 DAO를 사용하고 다른 방식으로 사용하지 않는 이유를 고려해야합니다.
Mihai Danila

6
DAO가 "읽기 및 쓰기"인 동안 리포지토리가 "읽기 전용"개념 인 이유는 무엇입니까?
Dennis

120

좋아, 내가 의견에 넣은 것을 더 잘 설명 할 수 있다고 생각한다. :). 따라서 기본적으로 DAO는 리포지토리보다 더 유연한 패턴이지만 둘 다 동일하게 볼 수 있습니다. 둘 다 사용하려면 DAO에서 저장소를 사용하십시오. 아래에 각각 설명하겠습니다.

저장소:

특정 유형의 객체를 저장하는 저장소입니다. 특정 유형의 객체를 검색하고 저장할 수 있습니다. 일반적으로 한 가지 유형의 객체 만 처리합니다. 예 AppleRepository를 들어 AppleRepository.findAll(criteria)또는 할 수 있습니다 AppleRepository.save(juicyApple). 리포지토리는 도메인 모델 용어 (DB 용어가 아님-데이터가 어디서나 유지되는 방법과 관련이 없음)를 사용하고 있습니다.

리포지토리는 모든 데이터를 동일한 테이블에 저장하지만 패턴에는 필요하지 않습니다. 한 가지 유형의 데이터 만 처리하므로 하나의 기본 테이블 (DB 지속성에 사용되는 경우)에 논리적으로 연결됩니다.

DAO-데이터 액세스 객체 (즉, 데이터에 액세스하는 데 사용되는 객체)

DAO는 데이터를 찾는 클래스입니다 (주로 파인더이지만 일반적으로 데이터를 저장하는 데 사용됨). 이 패턴은 동일한 유형의 데이터를 저장하도록 제한하지 않으므로 관련 객체를 찾고 저장하는 DAO를 쉽게 가질 수 있습니다.

예를 들어 다음과 같은 메소드를 노출하는 UserDao를 쉽게 가질 수 있습니다.

Collection<Permission> findPermissionsForUser(String userId)
User findUser(String userId)
Collection<User> findUsersForPermission(Permission permission)

이들은 모두 사용자 (및 보안)와 관련이 있으며 동일한 DAO에서 지정할 수 있습니다. 리포지토리의 경우에는 해당되지 않습니다.

드디어

두 패턴 모두 실제로는 동일하지만 (데이터를 저장하고 액세스를 추상화하며 도메인 모델에 더 가깝게 표현되고 DB 참조를 거의 포함하지 않음), 사용 방식은 약간 다를 수 있습니다. 좀 더 유연하고 일반적인 반면 리포지토리는 좀 더 구체적이고 유형에만 제한적입니다.


내가 이것을 올바르게 얻는다면, CarDescription예를 language_id들어 외래 키 와 같은 것을 가지고 있습니다. 그런 다음 검색하면 다음과 같이해야합니다 : CarRepository.getAll(new Criteria(carOwner.id, language.id));특정 언어로 된 모든 언어의 자동차를 줄 것입니다. ?
표시 이름

@StefanFalk, Spring Data를 살펴보면 그보다 훨씬 좋은 통화를 할 수 있습니다. 예를 들어 CarRepository.findByLanguageId(language.id), 코드를 작성할 필요가 없으며 코드를 작성할 필요조차 없으며, 해당 이름의 메소드로 인터페이스를 정의하기 만하면 스프링 데이터가 기본 클래스 구현을 관리합니다. 아주 깔끔한 것들;)
Stef

2
Spring Data의 장점은 실제로 쿼리를 작성할 필요가 없으며 인터페이스를 작성하는 것입니다 (예제에서 TodoRepository와 같은 메소드가 있음 findById). 그리고 당신은 실제로 끝났습니다. SpringData는 리포지토리 인터페이스를 확장하고 클래스를 생성하는 모든 인터페이스를 찾습니다. 이러한 클래스를 볼 수 없으며 새 인스턴스를 만들 수는 없지만 인터페이스를 자동 연결하고 Spring이 해당 리포지토리 객체를 찾도록 할 필요는 없습니다.
Stef

1
마지막으로 Spring Data를 사용할 필요가 없으며 쿼리 API를 직접 작성하는 오래된 방법 (Criteria API 등 사용)을 사용할 수는 있지만 인생을 조금 더 복잡하게 만들 것입니다 ... 더 유연 해 지겠지만, 실제로 쿼리에 열중하고 싶을 때 스프링 데이터를 사용하면 @Query 어노테이션 또는 작동하지 않는 두 가지 방법을 사용할 수 있습니다. 자신 만의 구현을 처음부터 작성하는 것과 동일한 기능을 제공하는 확장 인 사용자 정의 저장소를 작성하십시오.
Stef

2
"집계 된 루트"는 종종 저장소 패턴에 연결된 용어입니다. 저장소 정의와 함께 어떻게 사용할 것인지 모르겠습니다.
Christian Strempfer 17

90

DAO 및 리포지토리 패턴은 DAL (Data Access Layer)을 구현하는 방법입니다. 먼저 DAL부터 시작하겠습니다.

데이터베이스에 액세스하는 객체 지향 응용 프로그램에는 데이터베이스 액세스를 처리 할 논리가 있어야합니다. 코드를 깨끗하고 모듈 식으로 유지하려면 데이터베이스 액세스 논리를 별도의 모듈로 분리하는 것이 좋습니다. 계층 구조에서이 모듈은 DAL입니다.

지금까지 특정 구현에 대해서는 언급하지 않았습니다. 데이터베이스 액세스 로직을 별도의 모듈에 배치하는 일반적인 원칙 만 있습니다.

이제이 원리를 어떻게 구현할 수 있습니까? 글쎄, 특히 Hibernate와 같은 프레임 워크에서 이것을 구현하는 방법 중 하나는 DAO 패턴입니다.

DAO 패턴은 일반적으로 각 도메인 엔터티에 자체 DAO가있는 DAL을 생성하는 방법입니다. 예를 들어 UserUserDao, Appointment그리고 AppointmentDao: 하이버 네이트 등으로 DAO의 예 http://gochev.blogspot.ca/2009/08/hibernate-generic-dao.html .

그렇다면 리포지토리 패턴은 무엇입니까? DAO와 마찬가지로 리포지토리 패턴도 DAL을 달성하는 방법입니다. 리포지토리 패턴의 주요 요점은 클라이언트 / 사용자 관점에서 컬렉션으로 보이거나 동작해야한다는 것입니다. 컬렉션처럼 동작한다는 것은 컬렉션처럼 인스턴스화해야한다는 의미는 아닙니다 Collection collection = new SomeCollection(). 대신 추가, 제거, 포함 등과 같은 작업을 지원해야 함을 의미합니다. 이것이 리포지토리 패턴의 본질입니다.

실제로, 예를 들어 Hibernate를 사용하는 경우에, 리포지토리 패턴은 DAO로 실현된다. 즉, DAL의 인스턴스는 DAO 패턴 및 리포지토리 패턴의 인스턴스 일 수 있습니다.

리포지토리 패턴은 반드시 DAO를 기반으로 구축 된 것은 아닙니다 (일부 사람들이 암시 할 수 있음). DAO가 위에서 언급 한 작업을 지원하는 인터페이스로 디자인 된 경우 DAO는 리포지토리 패턴의 인스턴스입니다. DAO가 이미 컬렉션과 유사한 작업 세트를 제공하는 경우 추가 계층이 필요한 이유는 무엇입니까?


5
"DAO가 이미 컬렉션과 유사한 작업 세트를 제공하는 경우 그 위에 추가 계층이 필요합니까?" 애완 동물 상점을 모델링하고 있고 콘크리트 애완 동물의 표 '애완 동물'표에서 참조하는 다른 동물과 그 속성 (이름 : "고양이", 유형 : "포유류"등)이있는 표 '애완 동물 유형'이 있다고 가정합니다. 가게에 있습니다 (이름 : "Katniss", 번식 : "Calico"등). 당신이 데이터베이스에없는 이미 종류의 동물을 추가 할 경우의 DAO에 커플 링 방지 한 방법 (애완 동물에 대한 다른 PetType과를 만드는 일을) 두 개의 별도의 DAO 호출 그룹에 저장소를 사용할 수 있습니다
매트

1
훌륭한 설명, 선생님!
Paul-Sebastian Manole

74

솔직히 이것은 기술적 구분이 아닌 의미 론적 구분처럼 보입니다. 데이터 액세스 개체라는 문구는 "데이터베이스"를 전혀 의미하지 않습니다. 그리고 데이터베이스 중심으로 디자인 할 수 있지만 대부분의 사람들은 디자인 결함을 고려할 것이라고 생각합니다.

DAO의 목적은 데이터 액세스 메커니즘의 구현 세부 사항을 숨기는 것입니다. 리포지토리 패턴은 어떻게 다릅니 까? 내가 알 수있는 한 그렇지 않습니다. 리포지토리를 말하는 것은 DAO 와 다릅니다. 개체 컬렉션을 처리 / 반환하고 있기 때문에 옳지 않습니다. DAO는 개체 컬렉션을 반환 할 수도 있습니다.

저장소 패턴에 대해 읽은 모든 것은 나쁜 DAO 디자인 대 좋은 DAO 디자인 (일명 리포지토리 디자인 패턴)과 같은 구별에 의존하는 것 같습니다.


5
네, 완전히 동의합니다. 그것들은 본질적으로 동일합니다. DAO는 더 많은 DB 관련 사운드를 제공하지만 그렇지 않습니다. 리포지토리와 마찬가지로 데이터의 위치와 방법을 숨기는 데 사용되는 추상화 일뿐입니다.
Stef

+1이 문장. 솔직히 이것은 기술적 구분이 아닌 의미 론적 구분처럼 보입니다. 데이터 액세스 개체라는 문구는 "데이터베이스"를 전혀 의미하지 않습니다.
Sudhakar Chavali

1
리포지토리와 컬렉션을 비교할 때 요점은 개체 컬렉션을 처리 / 반환하는 것이 아니라 리포지토리 컬렉션 자체 처럼 동작 한다는 것입니다. 예를 들어 Java의 경우 컬렉션의 객체를 수정할 때 자동으로 업데이트되기 때문에 리포지토리에 업데이트 방법이 없다는 것을 의미합니다 (Java 컬렉션은 객체에 대한 참조 만 저장하기 때문).
Christoph Böhme

17

리포지토리는 도메인 기반 디자인의 일부인 더 추상적 인 도메인 지향 용어이며, 도메인 디자인 및 공통 언어의 일부이며, DAO는 데이터 액세스 기술에 대한 기술적 추상화이며, 리포지토리는 기존 데이터 및 팩토리를 관리하기위한 팩토리에만 관심이 있습니다. 데이터.

다음 링크를 확인하십시오.

http://warren.mayocchi.com/2006/07/27/repository-or-dao/ http://fabiomaulo.blogspot.com/2009/09/repository-or-dao-repository.html


6

주요 차이점은 리포지토리는 집계의 집계 루트에 대한 액세스를 처리하고 DAO는 엔터티에 대한 액세스를 처리한다는 것입니다. 따라서 저장소가 집계 루트의 실제 지속성을 DAO에 위임하는 것이 일반적입니다. 또한 집계 루트가 다른 엔티티의 액세스를 처리해야하므로이 액세스를 다른 DAO에 위임해야 할 수도 있습니다.


5

DAO는 데이터베이스 / 데이터 파일 또는 기타 지속성 메커니즘에 대한 추상화를 제공하여 구현 세부 사항을 몰라도 지속성 계층을 조작 할 수 있습니다.

리포지토리 클래스에서는 단일 리포지토리 메서드 내에서 여러 DAO 클래스를 사용하여 "앱 관점"에서 작업을 수행 할 수 있습니다. 따라서 도메인 계층에서 여러 DAO를 사용하는 대신 리포지토리를 사용하여 완료하십시오. 리포지토리는 다음 과 같은 일부 응용 프로그램 논리를 포함 할 수있는 계층입니다 . 메모리 내 캐시에서 데이터를 사용할 수있는 경우 캐시에서 데이터를 가져 오면 네트워크에서 데이터를 가져 와서 다음 번 검색을 위해 메모리 내 캐시에 저장합니다.


3

리포지토리는 잘 설계된 DAO 일뿐입니다.

ORM은 테이블 중심이지만 DAO는 아닙니다.

DAO 자체는 자동차가 어디서 어떻게 유지되는지에 관계없이 ORM 리포지토리 / 엔티티 또는 DAL 공급자와 정확히 동일하게 수행 할 수 있으므로 저장소에서 여러 DAO를 사용할 필요가 없습니다. 1 테이블, 2 테이블, n 테이블, 반 테이블 웹 서비스, 테이블 및 웹 서비스 등. 서비스는 여러 DAO / 저장소를 사용합니다.

내 DAO는 CarDao가 Car DTO 만 처리한다고 가정합니다. 즉, 입력 된 Car DTO 만 가져오고 출력 된 Car DTO 또는 Car DTO 컬렉션 만 반환합니다.

따라서 리포지토리와 마찬가지로 DAO는 실제로 비즈니스 로직의 IoC이므로 사이트 간 전략이나 레거시로 사이트 간 인터페이스를 위협하지 않습니다. DAO는 지속성 전략을 캡슐화하고 도메인 관련 persitence 인터페이스를 제공합니다. 저장소는 잘 정의 된 DAO 실제가 무엇인지 이해하지 못한 사람들에게 또 다른 단어입니다.


우선 "ORM 저장소 / 엔터티"? 당신은 ORM 엔티티를 의미합니다. ORM의 저장소와 같은 것은 없습니다. 두 번째 ORM은 일반적으로 엔티티 만 처리합니다. 도메인 모델. DAO는 테이블을 직접 처리하고 추상적 인 데이터 액세스를 처리합니다. 그들은 엔터티도 반환합니다. 저장소는 엔티티를 가져 오기위한 콜렉션 인터페이스를 제공하는 가장 높은 추상화입니다. DAO는 저장소 일 수 있습니다. 실제 스토리지 엔진을 추상화하고 인터페이스를 제공하며 (캐시) 엔티티의 컬렉션보기를 제공합니다. DAO는 ORM을 사용하여 데이터베이스와 인터페이스하고 엔터티 작업을 위임 할 수 있습니다.
Paul-Sebastian Manole

3
@brokenthorn에 동의하십시오. 그의 의견에서 가장 중요한 점은 "리포지토리가 가장 높은 추상화입니다"이며,이 추상화는 기본 데이터베이스 기술로부터 도메인 코드를 보호하려는 경우에 필수적입니다. ORM / 어댑터 / DB 드라이버 개념은 DAO로 유출되는 경향이 있습니다. 둘 이상의 데이터베이스 기술을 지원하는 응용 프로그램이 있거나 응용 프로그램을 데이터베이스에 고정하지 않으려는 경우 도메인 모델에서 직접 DAO를 사용하는 것은 번거롭지 않습니다.
Subhash Bhushan

2

0

매우 간단한 문장으로 : DAO가 데이터베이스에 더 가깝고 종종 테이블 중심이되는 반면 리포지토리는 컬렉션을 나타냅니다.


DAO는 컬렉션 / 오브젝트도 나타낼 수 있습니다.
Yousha Aleayoub

0

스프링 프레임 워크에는 저장소라는 주석이 있으며이 주석에 대한 설명에는 저장소에 대한 유용한 정보가 있습니다.이 토론에 유용하다고 생각합니다.

어노테이션이있는 클래스는 원래 도메인 기반 설계 (Evans, 2003)에서 "개체 콜렉션을 에뮬레이트하는 스토리지, 검색 및 검색 동작을 캡슐화하는 메커니즘"으로 정의 된 "리포지토리"임을 나타냅니다.

"데이터 액세스 오브젝트"와 같은 전통적인 Java EE 패턴을 구현하는 팀도이 스테레오 타입을 DAO 클래스에 적용 할 수 있지만, 그렇게하기 전에 데이터 액세스 오브젝트와 DDD 스타일 저장소의 차이점을 이해하도록주의를 기울여야합니다. 이 주석은 범용 고정 관념이며 개별 팀은 의미를 좁히고 적절하게 사용할 수 있습니다.

이렇게 주석이 달린 클래스는 PersistenceExceptionTranslationPostProcessor와 함께 사용될 때 Spring DataAccessException 변환에 적합합니다. 주석이 달린 클래스는 툴링, 측면 등을 목적으로 전체 응용 프로그램 아키텍처에서의 역할에 대해서도 명확합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.