2011-08-09 45 views
4

我目前正在研究这个讨论来的项目,我想问问他人他们对此有什么看法。 (根据维基百科):“在计算机软件中,数据访问对象(DAO)是一种为某种类型的数据库或持久性机制提供抽象接口的对象,提供了一些特定的操作而不暴露细节的数据库。“。ORM和DAO - 设计问题

但是,使用ORM这显然是一个ORM(例如Hibernate)的工作。它恰好为某些(几乎任何)类型的数据库提供了一个抽象接口。

回顾几个最后的项目让我们看看DAO层。第一步是使用save(),findById(),findAll()方法的通用hibernate dao。这对我来说只是代理hibernate会话方法。

更进一步我看到这样的接口,像这里提出的:Generic DAO pattern in Hibernate,DAO完全紧密地将hibernate的方式做到持久性(合并,标准查询)。这个DAO不会与Hibernate一起用于其他持久机制。

所以最后的问题是一个问题:对于这种常见的DAO设计,什么新的带来了DAO模式?如果我想切换数据库引擎,我将它切换到休眠级别。那么,这对于在ORM应用程序中使用DAO模式是否有任何好处?

让我们收集了一些经验:

  1. 有多少次你看到的DAO类层次结构紧密结合的休眠(或其他ORM)和你想想从什么好处?
  2. 你有多少项目以你从DAO层获益的方式改变了持久性机制(即你需要实现其他DAO层,因为你的作业不能通过切换db方言在ORM级上完成)?
  3. 有多少个项目你刚刚开发了大型的DAO结构(每个领域对象的接口+类)并且从来没有真正使用过这个(即,你从未改变过基本DAO层次结构的实现)?
  4. 那么,您认为没有DAO层的应用程序,只使用ORM会话提供的抽象?

请与经验分享。

回答

2

恕我直言,当使用ORM时,DAO模式并不是真的关于切换数据库引擎的能力。这是关于

  • 分离职责:业务逻辑进入服务层,持久转到DAO层
  • 能够通过嘲讽DAO层
  • 能够测试持久性测试服务层逻辑,因为它不是埋在业务逻辑之内

我通常不希望每个域对象都有一个DAO,而是每个功能用例都有一个DAO。事实上,我发现大多数查询在一个足够复杂的应用程序中并没有链接到特定的域对象,而是与用例或一组用例相关联。但是YMMV,并且结合这两种方法有时是有用的。

因此,要回答你的具体问题:

  1. 几乎总是。使用Hibernate或JPA使用DAO与使用普通JDBC使用DAO不同,绝大多数时间都不使用DAO。通常,数据库的选择在项目开始之前就已经完成,并且永远不会改变。
  2. 我倾向于只在需要时开发DAO,而不是因为存在域对象。但是有一个“通用DAO”基类有时很方便
  3. 我认为它们很难测试,通常结构不是很好,最终一次又一次地重复实现相同的查询/加载,因为它们不是孤立的一个可重复使用的DAO
+0

感谢您的回复。然后,我还有另外一个问题: 1.你不能在服务层上模拟和测试,在默认实现中直接使用Session抽象吗? 2.“DAO per usecase”是什么意思?这对我来说是新的,因为我也使用这种模式,但在服务层 我知道这种方法的另一个问题是收集某处访问数据的方法 - 复杂的,可重复的查询。这可能是默认在DAO层完成的,但通常这是重复的服务层,它们只是这些DAO的代理(从我看不到太多好处)。 –

+0

1.不是,因为会话方法太粗糙,而且不够具体。模拟(并验证)dao.findFoosByField(String)比session.createQuery(String)更容易,然后是query.setMaxResults(),然后是query.list()。 2.例如,我可能有一个用于授权管理的DAO,它将处理用户,角色,配置文件的持久性,而不是一个用户DAO,另一个用于角色,另一个用于配置文件。 –

+0

好的,我明白了。我使用DB群体进行测试而不是嘲笑,所以嘲笑的DAO并没有真正帮助我。我在这里看到的另一个与DAO的东西是限制/排序的问题。在结果中,需要大量的这些参数需要的方法,而这一切都已经暴露出了一个非常方便的界面。我真的很接近转向不同的解决方案。 –