数据访问对象(DAO)和存储库模式之间的区别是什么?我正在开发一个应用程序,使用企业Java bean (EJB3), Hibernate ORM作为基础设施,领域驱动设计(DDD)和测试驱动开发(TDD)作为设计技术。
当前回答
如果我们考虑设计模式DAO和Repository的原始定义,就会发现它们非常相似。主要的区别是字典和它们的来源(Oracle vs. Fowler)。
引用:
DAO - "separates a data resource's client interface from its data access mechanisms" and "The DAO implements the access mechanism required to work with the data source. The data source could be a persistent store like an RDBMS, an external service like a B2B exchange, a repository like an LDAP database, or a business service accessed via CORBA Internet Inter-ORB Protocol (IIOP) or low-level sockets." Repository - "Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects." and "Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers."
基于这些引用,这两种设计模式都调解了领域层和数据层之间的通信。此外,Repository与ORM相关联,而DAO则是用于从任何地方访问数据的更通用的接口。
其他回答
存储库不过是设计良好的DAO。
ORM是以表为中心的,而不是DAO。
没有必要在存储库中使用多个DAO,因为DAO本身可以对ORM存储库/实体或任何DAL提供者做完全相同的事情,无论汽车在哪里以及如何持久化1个表、2个表、n个表、半个表、一个web服务、一个表和一个web服务等等。 服务使用多个DAO/存储库。
我自己的DAO,假设CarDao只处理Car DTO,我的意思是,只在输入中接收Car DTO只在输出中返回Car DTO或Car DTO集合。
因此,就像Repository一样,对于业务逻辑来说,DAO实际上是一个IoC,允许持久性接口不受持久性策略或遗留问题的影响。 DAO既封装了持久性策略,也提供了与域相关的持久性接口。 对于那些不理解定义良好的DAO实际上是什么的人来说,存储库只是另一个词。
DAO提供了对数据库/数据文件或任何其他持久性机制的抽象,因此,持久性层可以在不知道其实现细节的情况下进行操作。
而在Repository类中,可以在单个Repository方法中使用多个DAO类来从“应用程序角度”完成操作。因此,与其在域层使用多个DAO,不如使用存储库来完成它。 存储库是一个层,它可能包含一些应用逻辑,例如:如果数据在内存缓存中可用,那么从缓存中获取它,否则,从网络中获取数据并将其存储在内存缓存中,以便下次检索。
dao可能并不总是显式地与Only DataBase相关,
它可以只是一个访问数据的接口,在这种情况下,数据可以从DB/Cache甚至REST(现在不太常见,因为我们可以很容易地在各自的REST /IPC客户端中分离它们)访问。
这种方法中的回购可以由任何ORM解决方案实现,如果底层缓存/回购发生变化,它不会被传播/影响服务/业务层。
dao可以接受/返回域类型。考虑一个学生域,关联的DAO类将是StudentDao
StudentDao {
StudentRepository,
StudentCache,
Optional<Student> getStudent(Id){
// Use StudentRepository/StudentCache to Talk to DD & Cache
// Cache Type can be the same as Domain Type, DB Type(Entities) should be a Same/Different Type.
}
Student updateStudent(Student){
// Use StudentRepository/StudentCache to Talk to DD & Cache
// Cache Type can be the same as Domain Type, DB Type(Entities) should be a Same/Different Type.
}
}
dao可以接受/返回子域类型。考虑一个学生域,它有子域,比如考勤/科目,它有一个DAO类StudentDao,
StudentDao {
StudentRepository, SubjectRepository, AttendanceRepository
StudentCache, SubjectCache, AttendanceCache
Set<Subject> getStudentSubject(Id){
// Use SubjectRepository/SubjectCache to Talk to DD & Cache
}
Student addNewSubjectToStudent(ID, Subject){
// Use SubjectRepository/SubjectCache to Talk to DD & Cache
}
}
DAO是数据持久性的抽象。 存储库是对象集合的抽象。
DAO被认为更接近数据库,通常以表为中心。 存储库将被认为更接近域,只处理聚合根。
存储库可以使用DAO来实现,但您不会做相反的事情。
另外,Repository通常是一个更窄的接口。它应该是一个简单的对象集合,包含Get(id)、Find(isspec)、Add(Entity)。
像Update这样的方法适用于DAO,但不适用于Repository——当使用Repository时,对实体的更改通常由单独的UnitOfWork跟踪。
被称为Repository的实现实际上更像是一个DAO,这似乎很常见,因此我认为它们之间的区别存在一些混淆。
如果我们考虑设计模式DAO和Repository的原始定义,就会发现它们非常相似。主要的区别是字典和它们的来源(Oracle vs. Fowler)。
引用:
DAO - "separates a data resource's client interface from its data access mechanisms" and "The DAO implements the access mechanism required to work with the data source. The data source could be a persistent store like an RDBMS, an external service like a B2B exchange, a repository like an LDAP database, or a business service accessed via CORBA Internet Inter-ORB Protocol (IIOP) or low-level sockets." Repository - "Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects." and "Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers."
基于这些引用,这两种设计模式都调解了领域层和数据层之间的通信。此外,Repository与ORM相关联,而DAO则是用于从任何地方访问数据的更通用的接口。
推荐文章
- 如何在JSON中使用杰克逊更改字段名
- 在Hibernate中重新连接分离对象的正确方法是什么?
- 一对多、多对一、多对多的区别?
- Hibernate中不同的保存方法之间有什么区别?
- 有人能解释一下JPA和Hibernate中的mappedBy吗?
- 什么是领域驱动设计?
- 使Hibernate忽略未映射的实例变量
- javax.transaction.Transactional vs . org.springframework.transaction.annotation.Transactional
- buildSessionFactory()配置方法在Hibernate中已弃用?
- 存储库和服务层的区别?
- DDD -实体不能直接访问存储库的规则
- JPA orphanRemoval=true如何不同于ON DELETE CASCADE DML子句
- 如何映射一个组合键与JPA和Hibernate?
- 如何使用旧版本的Hibernate(~2009)来计算行数?
- 我如何使JPA OneToOne关系变懒