Antworten:
DAO
ist eine Abstraktion der Datenpersistenz .
Repository
ist eine Abstraktion einer Sammlung von Objekten .
DAO
würde näher an der Datenbank betrachtet werden, oft tabellenzentriert.
Repository
würde als näher an der Domäne betrachtet und nur in aggregierten Wurzeln behandelt.
Repository
könnte mit DAO
's implementiert werden , aber Sie würden nicht das Gegenteil tun.
Außerdem ist a Repository
im Allgemeinen eine engere Schnittstelle. Es sollte einfach eine Sammlung von Objekten sein, mit einem Get(id)
, Find(ISpecification)
, Add(Entity)
.
Eine Methode wie Update
ist für a geeignet DAO
, aber nicht für a. Repository
Bei Verwendung von a Repository
werden Änderungen an Entitäten normalerweise von einer separaten UnitOfWork verfolgt.
Es scheint üblich zu sein, Implementierungen zu sehen, die als a Repository
bezeichnet werden und wirklich eher a sind DAO
, und daher denke ich, dass es einige Verwirrung über den Unterschied zwischen ihnen gibt.
OK, denke ich kann besser erklären, was ich in die Kommentare geschrieben habe :). Grundsätzlich können Sie also beide als gleich ansehen, obwohl DAO ein flexibleres Muster als Repository ist. Wenn Sie beide verwenden möchten, verwenden Sie das Repository in Ihren DAOs. Ich werde jeden von ihnen unten erklären:
Es ist ein Repository für einen bestimmten Objekttyp - es ermöglicht Ihnen, nach einem bestimmten Objekttyp zu suchen und diese zu speichern. Normalerweise werden NUR ein Objekttyp behandelt. ZB AppleRepository
würde dir erlauben zu tun AppleRepository.findAll(criteria)
oder AppleRepository.save(juicyApple)
. Beachten Sie, dass das Repository Domänenmodellbegriffe verwendet (keine DB-Begriffe - nichts damit zu tun, wie Daten irgendwo gespeichert werden).
Ein Repository speichert höchstwahrscheinlich alle Daten in derselben Tabelle, während das Muster dies nicht erfordert. Die Tatsache, dass es nur einen Datentyp verarbeitet, macht es logisch mit einer Haupttabelle verbunden (wenn es für die DB-Persistenz verwendet wird).
Ein DAO ist eine Klasse, die Daten für Sie findet (es ist meistens ein Finder, wird aber häufig auch zum Speichern der Daten verwendet). Das Muster beschränkt Sie nicht darauf, Daten desselben Typs zu speichern, sodass Sie problemlos ein DAO haben können, das verwandte Objekte findet / speichert.
ZB können Sie leicht UserDao haben, das Methoden wie verfügbar macht
Collection<Permission> findPermissionsForUser(String userId)
User findUser(String userId)
Collection<User> findUsersForPermission(Permission permission)
Alle diese beziehen sich auf den Benutzer (und die Sicherheit) und können unter demselben DAO angegeben werden. Dies ist beim Repository nicht der Fall.
Beachten Sie, dass beide Muster wirklich dasselbe bedeuten (sie speichern Daten und abstrahieren den Zugriff darauf und sie werden beide näher am Domänenmodell ausgedrückt und enthalten kaum eine DB-Referenz), aber die Art und Weise, wie sie verwendet werden, kann geringfügig unterschiedlich sein, DAO etwas flexibler / allgemeiner, während das Repository etwas spezifischer und nur auf einen Typ beschränkt ist.
CarDescription
, zB language_id
wenn ich so etwas habe, zB als Fremdschlüssel - dann CarRepository.getAll(new Criteria(carOwner.id, language.id));
ist es der richtige Weg, um herauszufinden, dass ich so etwas tun sollte: was mir alle Autos einer Sprache in einer bestimmten Sprache geben würde ?
CarRepository.findByLanguageId(language.id)
Zum Beispiel könnte das so geschrieben werden und Sie müssten nicht einmal den Code schreiben. Sie definieren einfach die Schnittstelle mit einer Methode mit diesem Namen und Spring Data kümmert sich um die Erstellung der Standardklassenimplementierung für Sie. Ziemlich ordentliches Zeug;)
findById
). Und Sie sind praktisch fertig. Spring Data findet dann alle von Ihnen erstellten Schnittstellen, die die Repository-Schnittstelle erweitern, und erstellt die Klassen für Sie. Sie werden diese Klassen nie sehen und können keine neuen Instanzen erstellen, müssen dies jedoch nicht, da Sie die Schnittstelle einfach automatisch verdrahten und Spring das Repository-Objekt lokalisieren lassen können.
DAO- und Repository-Muster sind Möglichkeiten zur Implementierung von Data Access Layer (DAL). Beginnen wir also zuerst mit DAL.
Objektorientierte Anwendungen, die auf eine Datenbank zugreifen, müssen über eine Logik für den Datenbankzugriff verfügen. Um den Code sauber und modular zu halten, wird empfohlen, die Datenbankzugriffslogik in ein separates Modul zu isolieren. In der Schichtarchitektur ist dieses Modul DAL.
Bisher haben wir nicht über eine bestimmte Implementierung gesprochen: nur ein allgemeines Prinzip, das die Datenbankzugriffslogik in ein separates Modul einfügt.
Wie können wir dieses Prinzip nun umsetzen? Ein bekannter Weg, dies zu implementieren, insbesondere mit Frameworks wie Hibernate, ist das DAO-Muster.
Das DAO-Muster ist eine Methode zum Generieren von DAL, bei der normalerweise jede Domänenentität über ein eigenes DAO verfügt. Zum Beispiel User
und UserDao
, Appointment
und AppointmentDao
usw. Ein Beispiel für DAO mit Ruhezustand: http://gochev.blogspot.ca/2009/08/hibernate-generic-dao.html .
Was ist dann das Repository-Muster? Wie DAO ist auch das Repository-Muster ein Weg, um DAL zu erreichen. Der Hauptpunkt im Repository-Muster ist, dass es aus Client / Benutzer-Sicht als Sammlung aussehen oder sich so verhalten sollte. Was bedeutet, sich wie eine Sammlung zu verhalten, ist nicht, dass sie wie eine Sammlung instanziiert werden mussCollection collection = new SomeCollection()
. Stattdessen bedeutet dies, dass Vorgänge wie Hinzufügen, Entfernen, Enthalten usw. unterstützt werden sollen. Dies ist die Essenz des Repository-Musters.
In der Praxis wird beispielsweise bei Verwendung des Ruhezustands das Repository-Muster mit DAO realisiert. Das heißt, eine Instanz von DAL kann gleichzeitig eine Instanz von DAO-Muster und Repository-Muster sein.
Das Repository-Muster ist nicht unbedingt etwas, das man auf DAO aufbaut (wie einige vielleicht vorschlagen). Wenn DAOs mit einer Schnittstelle entworfen wurden, die die oben genannten Operationen unterstützt, handelt es sich um eine Instanz des Repository-Musters. Denken Sie darüber nach: Wenn DAOs bereits eine sammlungsähnliche Reihe von Operationen bereitstellen, was ist dann die Notwendigkeit einer zusätzlichen Ebene darüber?
Ehrlich gesagt sieht dies nach einer semantischen Unterscheidung aus, nicht nach einer technischen Unterscheidung. Der Ausdruck Datenzugriffsobjekt bezieht sich überhaupt nicht auf eine "Datenbank". Und obwohl Sie es datenbankzentriert gestalten könnten, würden die meisten Leute dies als Konstruktionsfehler betrachten.
Der Zweck des DAO besteht darin, die Implementierungsdetails des Datenzugriffsmechanismus zu verbergen. Wie unterscheidet sich das Repository-Muster? Soweit ich das beurteilen kann, ist es das nicht. Die Aussage, dass ein Repository sich von einem DAO unterscheidet , weil Sie mit einer Sammlung von Objekten arbeiten / diese zurückgeben, kann nicht richtig sein. DAOs können auch Sammlungen von Objekten zurückgeben.
Alles, was ich über das Repository-Muster gelesen habe, scheint auf dieser Unterscheidung zu beruhen: schlechtes DAO-Design vs. gutes DAO-Design (auch bekannt als Repository-Design-Muster).
Repository ist ein abstrakterer domänenorientierter Begriff, der Teil des Domain Driven Design ist. Er ist Teil Ihres Domain-Designs und eine gemeinsame Sprache. DAO ist eine technische Abstraktion für die Datenzugriffstechnologie. Das Repository befasst sich nur mit der Verwaltung vorhandener Daten und Fabriken zur Erstellung von Daten.
Überprüfen Sie diese Links:
http://warren.mayocchi.com/2006/07/27/repository-or-dao/ http://fabiomaulo.blogspot.com/2009/09/repository-or-dao-repository.html
Der Hauptunterschied besteht darin, dass ein Repository den Zugriff auf die Aggregatwurzeln in einem Aggregat verwaltet, während DAO den Zugriff auf Entitäten verwaltet. Daher ist es üblich, dass ein Repository die tatsächliche Persistenz der aggregierten Wurzeln an ein DAO delegiert. Da der aggregierte Stamm den Zugriff der anderen Entitäten verarbeiten muss, muss er diesen Zugriff möglicherweise an andere DAOs delegieren.
DAO bietet eine Abstraktion für Datenbank- / Datendateien oder andere Persistenzmechanismen, sodass die Persistenzschicht ohne Kenntnis der Implementierungsdetails manipuliert werden kann.
Während in Repository-Klassen mehrere DAO-Klassen innerhalb einer einzelnen Repository-Methode verwendet werden können, um eine Operation aus der "App-Perspektive" auszuführen. Verwenden Sie also nicht mehrere DAO auf Domänenebene, sondern das Repository, um dies zu erledigen. Das Repository ist eine Schicht, die einige Anwendungslogiken enthalten kann, z. B .: Wenn Daten im In-Memory-Cache verfügbar sind, rufen Sie sie andernfalls aus dem Cache ab. Rufen Sie andernfalls Daten aus dem Netzwerk ab und speichern Sie sie beim nächsten Abruf im In-Memory-Cache.
Repository sind nichts anderes als gut gestaltete DAO.
ORM sind tabellenzentriert, aber nicht DAO.
Es ist nicht erforderlich, mehrere DAO im Repository zu verwenden, da DAO selbst mit ORM-Repositorys / -Entitäten oder jedem DAL-Anbieter genau dasselbe tun kann, unabhängig davon, wo und wie ein Auto bestehen bleibt. 1 Tabelle, 2 Tabellen, n Tabellen, eine halbe Tabelle, a Webdienst, eine Tabelle und ein Webdienst usw. Dienste verwenden mehrere DAO / Repositorys.
Mein eigenes DAO, sagen wir, CarDao befasst sich nur mit Auto-DTO, ich meine, nehme nur Auto-DTO als Eingabe und gebe nur Auto-DTO oder Auto-DTO-Sammlungen als Ausgabe zurück.
Genau wie das Repository ist DAO tatsächlich ein IoC für die Geschäftslogik, sodass Persistenzschnittstellen nicht durch Persistenzstrategien oder Vermächtnisse eingeschüchtert werden können. DAO kapselt sowohl die Persistenzstrategie als auch die domänenbezogene Persistenzschnittstelle. Repository ist nur ein weiteres Wort für diejenigen, die nicht verstanden haben, was eine genau definierte DAO-Aktualität ist.
Versuchen Sie herauszufinden, ob DAO oder das Repository-Muster für die folgende Situation am besten geeignet sind: Stellen Sie sich vor, Sie möchten eine einheitliche Datenzugriffs-API für einen dauerhaften Mechanismus für verschiedene Arten von Datenquellen wie RDBMS, LDAP, OODB, XML-Repositorys und bereitstellen flache Dateien.
Beachten Sie bei Interesse auch die folgenden Links:
http://www.codeinsanity.com/2008/08/repository-pattern.html
http://blog.fedecarg.com/2009/03/15/domain-driven-design-the-repository/
http://devlicio.us/blogs/casey/archive/2009/02/20/ddd-the-repository-pattern.aspx
in einem sehr einfachen Satz: Der wesentliche Unterschied besteht darin, dass Repositorys Sammlungen darstellen, während DAOs näher an der Datenbank liegen und häufig weitaus tabellenzentrierter sind.
Im Frühjahrs-Framework gibt es eine Annotation namens Repository, und in der Beschreibung dieser Annotation gibt es nützliche Informationen über das Repository, die meiner Meinung nach für diese Diskussion nützlich sind.
Gibt an, dass eine mit Anmerkungen versehene Klasse ein "Repository" ist, das ursprünglich von Domain-Driven Design (Evans, 2003) als "Mechanismus zum Einkapseln von Speicher-, Abruf- und Suchverhalten, das eine Sammlung von Objekten emuliert" definiert wurde.
Teams, die traditionelle Java EE-Muster wie "Datenzugriffsobjekt" implementieren, können dieses Stereotyp auch auf DAO-Klassen anwenden. Es sollte jedoch darauf geachtet werden, die Unterscheidung zwischen Datenzugriffsobjekt- und DDD-ähnlichen Repositorys zu verstehen, bevor Sie dies tun. Diese Anmerkung ist ein allgemeines Stereotyp, und einzelne Teams können ihre Semantik einschränken und gegebenenfalls verwenden.
Eine so kommentierte Klasse kann in Verbindung mit einem PersistenceExceptionTranslationPostProcessor für die Spring DataAccessException-Übersetzung verwendet werden. Die mit Anmerkungen versehene Klasse wird auch hinsichtlich ihrer Rolle in der gesamten Anwendungsarchitektur zum Zweck von Werkzeugen, Aspekten usw. geklärt.
IRepository
Schnittstelle buchstäblich implementiert . Sie möchten, dass Ihr Repository DAOs bei seiner Implementierung verwendet. Denken Sie daran, dass ein DAO ein Objekt pro Tabelle ist, während ein Repository fast immer mehrere DAOs verwenden muss, um eine einzelne Entität zu erstellen. Wenn Sie feststellen, dass dies nicht der Fall ist und Ihr Repository und Ihre Entität nur auf eine einzelne Tabelle zugreifen müssen, erstellen Sie höchstwahrscheinlich eine anämische Domäne.