数据访问对象(DAO)和存储库模式之间的区别是什么?我正在开发一个应用程序,使用企业Java bean (EJB3), Hibernate ORM作为基础设施,领域驱动设计(DDD)和测试驱动开发(TDD)作为设计技术。


当前回答

DAO提供了一种更简单的方式从存储中获取数据,隐藏了丑陋的查询。

存储库也处理数据并隐藏查询等,但是,存储库处理业务/域对象。

存储库将使用DAO从存储中获取数据,并使用该数据恢复业务对象。

例如,一个DAO可以包含一些类似-的方法

 public abstract class MangoDAO{
   abstract List<Mango>> getAllMangoes();
   abstract Mango getMangoByID(long mangoID);
}

一个存储库可以包含一些像这样的方法

   public abstract class MangoRepository{
       MangoDao mangoDao = new MangDao;

       Mango getExportQualityMango(){

       for(Mango mango:mangoDao.getAllMangoes()){
        /*Here some business logics are being applied.*/
        if(mango.isSkinFresh()&&mangoIsLarge(){
           mango.setDetails("It is an export quality mango");
            return mango;
           }
       }
    }
}

这个教程帮助我很容易地理解了主要概念。

其他回答

DAO是数据持久性的抽象。 存储库是对象集合的抽象。

DAO被认为更接近数据库,通常以表为中心。 存储库将被认为更接近域,只处理聚合根。

存储库可以使用DAO来实现,但您不会做相反的事情。

另外,Repository通常是一个更窄的接口。它应该是一个简单的对象集合,包含Get(id)、Find(isspec)、Add(Entity)。

像Update这样的方法适用于DAO,但不适用于Repository——当使用Repository时,对实体的更改通常由单独的UnitOfWork跟踪。

被称为Repository的实现实际上更像是一个DAO,这似乎很常见,因此我认为它们之间的区别存在一些混淆。

存储库是更抽象的面向领域的术语,是领域驱动设计的一部分,它是领域设计的一部分,是一种公共语言,DAO是数据访问技术的技术抽象,存储库只关心管理现有数据和创建数据的工厂。

查看这些链接:

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

尝试找出DAO或Repository模式是否最适用于以下情况: 假设您希望为各种类型的数据源(如RDBMS、LDAP、OODB、XML存储库和平面文件)的持久机制提供统一的数据访问API。

如果有兴趣,也可以参考以下链接:

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

http://en.wikipedia.org/wiki/Domain-driven_design

http://msdn.microsoft.com/en-us/magazine/dd419654.aspx

DAO提供了一种更简单的方式从存储中获取数据,隐藏了丑陋的查询。

存储库也处理数据并隐藏查询等,但是,存储库处理业务/域对象。

存储库将使用DAO从存储中获取数据,并使用该数据恢复业务对象。

例如,一个DAO可以包含一些类似-的方法

 public abstract class MangoDAO{
   abstract List<Mango>> getAllMangoes();
   abstract Mango getMangoByID(long mangoID);
}

一个存储库可以包含一些像这样的方法

   public abstract class MangoRepository{
       MangoDao mangoDao = new MangDao;

       Mango getExportQualityMango(){

       for(Mango mango:mangoDao.getAllMangoes()){
        /*Here some business logics are being applied.*/
        if(mango.isSkinFresh()&&mangoIsLarge(){
           mango.setDetails("It is an export quality mango");
            return mango;
           }
       }
    }
}

这个教程帮助我很容易地理解了主要概念。

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 
      
   
    }

}