Java 我找到了JPA,或者类似的,don';不鼓励道模式

Java 我找到了JPA,或者类似的,don';不鼓励道模式,java,hibernate,orm,jpa,dao,Java,Hibernate,Orm,Jpa,Dao,我发现JPA,或者类似的,不鼓励DAO模式。我不知道,但我有这种感觉,尤其是对于服务器管理的JTA管理器 在充分实践使用DAO模式之后,我开始围绕该模式设计基于JPA的应用程序。但它不适合我,我倾向于失去JPA的很多特性 好吧,假设您启动一个带有悲观锁定的查询,它从DAO方法返回一个Entite列表。返回时,事务结束,锁消失(服务器管理的JTA管理器的情况)。所以,不必客气地说。不过,也有一些有效的案例 另一个例子要简单得多。假设您触发一个查询以获取某个实体,该实体与其他实体之间存在一对多的延迟

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

在充分实践使用DAO模式之后,我开始围绕该模式设计基于JPA的应用程序。但它不适合我,我倾向于失去JPA的很多特性

好吧,假设您启动一个带有悲观锁定的查询,它从DAO方法返回一个Entite列表。返回时,事务结束,锁消失(服务器管理的JTA管理器的情况)。所以,不必客气地说。不过,也有一些有效的案例

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

因此,在我看来,最好不要专门制作DAO,而是在您的业务bean中进行,这样您将能够利用这些有用的特性。或者说,ORMAPI本身可以被视为DAO/数据层。所以,我们不需要再做一次

你们怎么看


注意:我并不是说DAO模式已经过时了。事实上,这取决于具体情况。

如果不将DAO本身定义为事务性的,就不会有这些问题

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

使用spring,您可以非常轻松地实现这一点。如果没有它,您可能会再次在DAO中包含事务逻辑,即
DAO.beginTransaction()
DAO.commitTransaction()
,并从服务层使用它

据我所知,您建议直接在服务类中使用
EntityManager
可能比使用包装器
DAO
类要好。我不同意有一个原因。在服务类中使用DAO类(最多是接口),您根本不依赖JPAAPI。您不必构造
Query
对象等。这可能不是一个很大的优势,但你会同意这是一个最佳实践。您可以在以后切换到纯JDBC、纯文本、XML或其他类型,只需更改DAO即可

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


因此,归根结底,回到你的观点——这要看情况而定。

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


在《关于InfoQ》一书中,您会发现一些其他开明的观点,但您不会对其内容和结论感到惊讶,这些内容和结论可以概括为:对于标准数据访问,您不再需要DAO模式,但是对于一些更复杂的情况,您可能需要它,但是没有它我们生活得更好。

DAO用于设计透视图,而JPA是数据访问函数的“官方”包装器。JPA不可能试图杀死DAO——它可以使DAO更容易实现,也许是如此简单,以至于DAO看起来如此简单,以至于可以忽略它。但是如果没有DAO层,设计的好处就不复存在了


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

“在服务类中使用DAO类(…),您根本不依赖JPA API。”好的,如果不这样做,您就依赖于EJB3,那又怎样?说真的,问题出在哪里?我不在乎依赖于标准API。当然,你仍然依赖于它,因为你使用它,这没有问题。但我的观点是,你可以很容易地改变持久性机制,而不需要修改所有的类,因为它们只依赖于DAO接口。@ BoZo我完全明白你的观点,但是我在10年中没有经常看到这种情况,并且认为这个事件是一种神话。+ 1,非常真实。即使在JPA环境中,DAO模式仍然是相关的,因为您的服务层是事务性的,一个事务可以跨越多个DAO调用。me neighter:)但也可以添加日志记录、访问检查等。现在DAO不是实现这一点的最佳场所。所以最终-这取决于:)(+1)我倾向于同意,如果一个人没有任何特别的想法,就没有理由创建dao层。即使是一个泛型DAO,更不用说实体的单独DAO类了。我一直在努力寻找一种测试Java EE JAX-RS/JPA代码的好方法,而试图获得一个可行的“测试中的容器”解决方案是一场噩梦。主要方面是尝试从测试中注入@Context PersistenceContext。我认为使用@EJBDAO和从测试和设置Dao中调用的构造函数将是干净的。Elton:我完全同意你的意思,没有任何if和but。然而,我想强调的是,分层并不是获得良好设计的唯一手段。因此,我不能同意你的这句绝对意义上的话,“没有图层意味着所有的设计优势不再存在”。我希望你明白我的意思。道层e