java 我发现 JPA 或类似的,不鼓励 DAO 模式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2100115/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
I found JPA, or alike, don't encourage DAO pattern
提问by Adeel Ansari
I found JPA, or alike, don't encourage DAO pattern. I don't know, but I feel like that, especially with server managed JTA managers.
我发现 JPA 或类似的东西不鼓励 DAO 模式。我不知道,但我有这种感觉,尤其是服务器管理的 JTA 管理器。
After adequate hands-on using DAO pattern, I started designing JPA based application around that pattern. But it doesn't fit in, IMO. I tend to lose quite a features of JPA and all.
在使用 DAO 模式进行了充分的实践之后,我开始围绕该模式设计基于 JPA 的应用程序。但它不适合,IMO。我倾向于失去 JPA 和所有功能的相当多的功能。
Well, suppose you fire a query with pessimistic locking and it returned a list of entites from a DAO method. Upon returning, transaction ends and lock is gone (a case with server managed JTA manager). So, no point, loosely speaking. There are valid cases, though.
好吧,假设您使用悲观锁定触发查询,并且它从 DAO 方法返回一个实体列表。返回时,事务结束并且锁消失(服务器管理的 JTA 管理器的情况)。所以,松散地说,没有意义。不过,也有有效的案例。
Another example is much more trivial. Suppose you fire a query to get some entity, that has a lazy loading one-to-many association with some other entity. Upon returning the DAO method, transaction ends. Lazy loading wouldn't work anymore, you simply get nullor something. To cope with that we load it eagerly manually. we do something like a.getBList().size().
另一个例子要简单得多。假设您触发查询以获取某个实体,该实体与某个其他实体具有延迟加载的一对多关联。返回 DAO 方法后,事务结束。延迟加载不再起作用,你只是得到null什么。为了解决这个问题,我们急切地手动加载它。我们做类似的事情a.getBList().size()。
Thus, IMO its better to not make a DAO exclusively, and do it in your business bean, this way you will be able to take advantage of those useful features. Or ORM API can be considered a DAO/Data-layer itself, arguably. So, we don't need to make another.
因此,IMO 最好不要专门制作 DAO,而是在您的业务 bean 中制作,这样您就可以利用这些有用的功能。或者 ORM API 可以被认为是 DAO/数据层本身,可以说。所以,我们不需要制作另一个。
What you folks think about it?
各位大佬怎么看?
Note: I don't say, by any means, that the DAO pattern is obsolete. Indeed it depends case to case.
注意:无论如何,我并不是说 DAO 模式已经过时。事实上,这取决于具体情况。
回答by Pascal Thivent
For simple applications, I don't see any problem in using the EntityManagerdirectly from EJBs and skipping the DAO pattern (I'm tired of writing too much code). And my feeling is indeed that this is what JPA and the Java EE API encourage. But it may still be justified for more complex applications (for data access from stored procedure, flat files...). So you are right, it depends :)
对于简单的应用程序,我认为EntityManager直接从 EJB 使用 和跳过 DAO 模式没有任何问题(我已经厌倦了编写太多代码)。我的感觉确实是 JPA 和 Java EE API 所鼓励的。但是对于更复杂的应用程序(从存储过程、平面文件访问数据...),它可能仍然是合理的。所以你是对的,这取决于:)
You'll find some other enlightened point of views in Has JPA Killed the DAO?on InfoQ but you won't be surprised by the content and the conclusion that can be summarized as: you don't really need the DAO pattern anymore for standard data access, you may however need it for some more complex situations, but we live better without it.
您会在Has JPA Killed the DAO 中找到其他一些开明的观点?在 InfoQ 上,但您不会对可以总结为的内容和结论感到惊讶:您真的不再需要 DAO 模式来进行标准数据访问,但是您可能在一些更复杂的情况下需要它,但我们生活没有它更好。
回答by Bozho
If you don't define the DAO itself to be transactional, you won't have those problems.
如果您不将 DAO 本身定义为事务性的,您就不会遇到这些问题。
The service layer is supposed to be transactional, because a transaction is supposed to span multiple operations. Putting each insert/update in a transaction is not the best scenario.
服务层应该是事务性的,因为一个事务应该跨越多个操作。将每个插入/更新放在事务中并不是最好的方案。
With spring you achieve that very easily. Without it you perhaps include the transaction logic in your DAO again - i.e. dao.beginTransaction()and dao.commitTransaction()and use that from the service layer instead.
使用 spring,您可以轻松实现这一目标。如果没有它,您可能会再次在您的 DAO 中包含事务逻辑——即dao.beginTransaction(),dao.commitTransaction()并从服务层使用它。
As I understand, you suggest that using the EntityManagerdirectly in the service classes is probably better than having a wrapper DAOclass. I don't agree for one reason. Working the DAO class (interface at best) in your service classes, you don't have dependency on the JPA API at all. You don't have to construct Queryobjects or the likes. This might not turn out to be a great advantage, but you'd agree it is a best practice. And you can later switch to plain JDBC, plain-text, XML, or whatever, by only changing the DAO.
据我了解,您建议EntityManager直接在服务类中使用 可能比使用包装DAO类更好。我不同意一个原因。在您的服务类中使用 DAO 类(最好是接口),您根本不需要依赖 JPA API。您不必构造Query对象或类似的东西。这可能不是一个很大的优势,但您会同意这是一种最佳实践。稍后您可以切换到纯 JDBC、纯文本、XML 或其他任何内容,只需更改 DAO。
This, although used widely as an example of why you should abstract something in another layer, is most often simply an overdesign. But sometimes the fact that all your database access operations are going through one place means you can add logging, access-level checks, etc. (Yes, sometimes the DAO is not a particularly suitable way to do this).
这虽然被广泛用作说明为什么应该在另一层中抽象某些东西的示例,但通常只是过度设计。但有时,您所有的数据库访问操作都经过一个地方这一事实意味着您可以添加日志记录、访问级别检查等(是的,有时 DAO 并不是一种特别合适的方式来执行此操作)。
So ultimately, to return to your point - it depends.
所以最终,回到你的观点 - 这取决于。
回答by Elton
DAO is used for design perspective, while JPA is some "Official" wrapper for data access functions. There's no way JPA is trying to kill DAO -- it can make DAO easier to implement, perhaps so easy that DAO looks so simple that it can be ignored. But without the DAO layer, the design benefit no longer exists.
DAO 用于设计透视图,而 JPA 是数据访问功能的一些“官方”包装器。JPA 不可能试图杀死 DAO——它可以使 DAO 更容易实现,也许很容易以至于 DAO 看起来如此简单以至于可以忽略它。但如果没有 DAO 层,设计优势将不复存在。
Of course, for "simple" projects, it can be ignored. Many things can be "ignored" if the project is "simple" enough.
当然,对于“简单”的项目,可以忽略。如果项目足够“简单”,很多事情都可以“忽略”。

