42

我发现 JPA 或类似的,不鼓励 DAO 模式。我不知道,但我有这种感觉,尤其是对于服务器管理的 JTA 管理器。

在使用 DAO 模式进行了充分的实践之后,我开始围绕该模式设计基于 JPA 的应用程序。但它不适合,IMO。我倾向于失去 JPA 的相当多的功能和所有功能。

好吧,假设您使用悲观锁定触发了一个查询,它从 DAO 方法返回了一个实体列表。返回后,事务结束并且锁定消失(服务器管理的 JTA 管理器的情况)。所以,没有意义,松散地说。不过,也有有效的案例。

另一个例子要简单得多。假设您触发查询以获取某个实体,该实体与其他实体具有延迟加载一对多关联。返回 DAO 方法后,事务结束。延迟加载将不再起作用,您只需获取null或其他东西。为了解决这个问题,我们急切地手动加载它。我们做类似的事情a.getBList().size()

因此,IMO 最好不要专门创建 DAO,而是在您的业务 bean 中进行,这样您就可以利用这些有用的功能。或者 ORM API 可以被认为是一个 DAO/数据层本身,可以说。所以,我们不需要再做一个。

大家怎么看呢?

注意:无论如何,我并不是说 DAO 模式已经过时。确实,这取决于具体情况。

4

3 回答 3

48

对于简单的应用程序,我认为直接使用 EJB 并跳过 DAO 模式没有任何问题EntityManager(我厌倦了编写太多代码)。我的感觉确实是 JPA 和 Java EE API 所鼓励的。但是对于更复杂的应用程序(对于从存储过程、平面文件...进行数据访问)来说,它仍然是合理的。所以你是对的,这取决于:)

您会在Has JPA Killed the DAO中找到其他一些开明的观点?在 InfoQ 上,但您不会对内容和结论感到惊讶,可以概括为:您实际上不再需要 DAO 模式来进行标准数据访问,但是您可能在一些更复杂的情况下需要它,但我们生活没有它会更好。

于 2010-01-20T09:41:57.373 回答
34

如果您不将 DAO 本身定义为事务性的,那么您将不会遇到这些问题。

服务层应该是事务性的,因为一个事务应该跨越多个操作。将每个插入/更新放入事务中并不是最好的方案。

使用弹簧,您可以轻松实现这一目标。如果没有它,您可能会再次在您的 DAO 中包含事务逻辑 - 即dao.beginTransaction()dao.commitTransaction()使用服务层中的事务逻辑。

据我了解,您建议EntityManager直接在服务类中使用可能比使用包装DAO类更好。我不同意,原因之一。在您的服务类中使用 DAO 类(最好是接口),您根本不依赖 JPA API。您不必构造Query对象或类似的东西。这可能不是一个很大的优势,但你会同意这是一个最佳实践。以后只需更改 DAO,您就可以切换到纯 JDBC、纯文本、XML 或其他任何东西。

尽管这被广泛用作为什么应该在另一层中抽象某些东西的示例,但通常只是过度设计。但有时,您的所有数据库访问操作都经过一个地方这一事实意味着您可以添加日志记录、访问级别检查等(是的,有时 DAO 并不是一种特别合适的方法)。

所以最终,回到你的观点 - 这取决于。

于 2010-01-20T09:14:18.750 回答
3

DAO 用于设计透视图,而 JPA 是数据访问功能的一些“官方”包装器。JPA 没有办法试图扼杀 DAO——它可以使 DAO 更易于实现,也许如此简单以至于 DAO 看起来如此简单以至于可以忽略。但如果没有 DAO 层,设计优势将不复存在。

当然,对于“简单”的项目,可以忽略。如果项目足够“简单”,很多事情都可以“忽略”。

于 2012-01-25T05:33:40.833 回答