我发现JPA,或类似的,不鼓励DAO模式。我不知道,但我觉得这样,尤其是服务器管理的JTA经理。
在使用DAO模式进行充分实践之后,我开始围绕该模式设计基于JPA的应用程序。但它不适合,IMO。我倾向于失去JPA和所有的功能。
好吧,假设您使用悲观锁定触发查询,并从DAO方法返回了一个entites列表。返回后,事务结束并且锁定消失(服务器管理的JTA管理器的情况)。所以,没有意义,松散地说。但是有一些有效的案例。
另一个例子更为微不足道。假设您触发查询以获取某个实体,该实体具有延迟加载与其他实体的一对多关联。返回DAO方法后,事务结束。延迟加载将不再起作用,您只需获取null
或其他内容。为了应对这种情况,我们热切地手动加载它。我们做的事情就像a.getBList().size()
。
因此,IMO最好不要专门创建DAO,并且在您的业务bean中执行它,这样您就可以利用这些有用的功能。或者可以说ORM API可以被认为是DAO /数据层本身。所以,我们不需要再制作另一个。
你们有什么想法呢?
注意:我不以任何方式说DAO模式已过时。事实上,这取决于具体情况。
答案 0 :(得分:47)
对于简单的应用程序,我没有看到直接从EJB使用EntityManager
并跳过DAO模式的任何问题(我厌倦了编写太多的代码)。我的感觉确实是JPA和Java EE API所鼓励的。但对于更复杂的应用程序(从存储过程,平面文件中进行数据访问......),它仍然是合理的。所以你是对的,这取决于:)
你会在InfoQ的Has JPA Killed the DAO?中找到一些其他开明的观点,但你不会对内容和结论感到惊讶,这些内容和结论可以概括为:你不再需要DAO模式了对于标准数据访问,您可能需要它来处理一些更复杂的情况,但没有它我们会生活得更好。
答案 1 :(得分:31)
如果您没有将DAO本身定义为事务性的,那么您将不会遇到这些问题。
服务层应该是事务性的,因为事务应该跨越多个操作。将每个插入/更新放入事务中并不是最佳方案。
春天你很容易实现。如果没有它,您可能会再次在DAO中包含事务逻辑 - 即dao.beginTransaction()
和dao.commitTransaction()
,并使用服务层中的事务逻辑。
据我了解,您建议直接在服务类中使用EntityManager
可能比使用包装器DAO
类更好。我不同意一个原因。在服务类中使用DAO类(接口最多),您根本不依赖于JPA API。您不必构造Query
个对象或类似对象。这可能不是一个很大的优势,但你同意这是一个最好的做法。您可以稍后通过仅更改DAO切换到纯JDBC,纯文本,XML或其他任何内容。
这虽然广泛用作为什么你应该在另一层中抽象的例子,但通常只是过度设计。但有时候,所有数据库访问操作都通过一个地方这一事实意味着您可以添加日志记录,访问级别检查等(是的,有时DAO不是特别适合的方式)。
所以最终,要回到你的观点 - 这取决于。
答案 2 :(得分:3)
DAO用于设计视角,而JPA是数据访问功能的“官方”包装器。 JPA没有办法试图杀死DAO - 它可以让DAO更容易实现,也许这么简单,DAO看起来很简单,可以忽略它。但是没有DAO层,设计优势就不复存在了。
当然,对于“简单”项目,可以忽略它。如果项目“足够简单”,很多事情都可以被“忽略”。