Hibernate vs JPA vs JDO - 每个的优缺点?[已关闭]

2022-08-31 06:47:42

我熟悉ORM这个概念,几年前我甚至在.NET项目中使用过nHibernate。但是,我没有跟上Java中ORM的主题,也没有机会使用这些工具中的任何一个。

但是,现在我可能有机会开始为我们的一个应用程序使用一些ORM工具,试图摆脱一系列遗留的Web服务。

我很难说出JPA规范之间的区别,你从Hibernate库本身得到什么,以及JDO所提供的东西。

所以,我知道这个问题有点开放,但我希望得到一些意见:

  • 每种方法的优缺点是什么?
  • 你会为新项目推荐哪一个?
  • 在某些情况下,使用一个框架与另一个框架相比是否有意义?

答案 1

一些注意事项:

  • JDO 和 JPA 都是规范,而不是实现。
  • 这个想法是,如果你将代码限制为仅使用标准JPA,则可以交换JPA实现。(JDO 同上。
  • 休眠可以用作JPA的一种实现。
  • 但是,Hibernate提供了一个本机API,其功能超越了JPA。

IMO,我会推荐Hibernate。


有一些关于如果您需要使用Hibernate特定功能应该怎么做的评论/问题。有很多方法可以看待这个问题,但我的建议是:

  • 如果您不担心供应商合作的前景,那么请在Hibernate和其他JPA和JDO实现之间进行选择,包括决策中的各种供应商特定扩展。

  • 如果您担心供应商绑定的前景,并且如果不诉诸供应商特定的扩展,就无法使用JPA,那么请不要使用JPA。(JDO 同上)。

实际上,您可能需要权衡您对供应商绑定的担忧程度与对这些供应商特定扩展的需求程度。

还有其他因素,例如您/您的员工对相应技术的了解程度,产品在许可方面的成本,以及您相信JDO和JPA未来会发生什么的故事。


答案 2

确保评估 JDO 的 DataNucleus 实现。我们从Hibernate开始,因为它似乎很受欢迎,但很快意识到它不是一个100%透明的持久性解决方案。有太多的警告,文档充满了“如果你有这种情况,那么你必须像这样编写你的代码”,这带走了我们想要的自由建模和编码的乐趣。JDO从未让我调整我的代码或模型以使其“正常工作”。我可以设计和编写简单的POJO,就好像我只打算在“内存中”使用它们一样,但我可以透明地保留它们。

与休眠相比,JDO/DataNucleus 的另一个优点是它没有所有的运行时反射开销,并且内存效率更高,因为它使用构建时字节代码增强功能(对于大型项目,可能会在构建时间增加 1 秒),而不是休眠的运行时反射驱动的代理模式。

你可能会觉得Hibernate令人讨厌的另一件事是,你必须参考你认为是对象的东西......它通常是对象的“代理”。如果没有字节码增强的好处,代理模式需要允许按需加载(即,在拉入顶级对象时避免拉入整个对象图)。准备好覆盖等于和哈希代码,因为您认为您正在引用的对象通常只是该对象的代理。

下面是一个示例,说明您在 Hibernate 上会遇到的挫折,而 JDO 不会遇到这些挫折:


http://blog.andrewbeacock.com/2008/08/how-to-implement-hibernate-safe-equals.html http://burtbeckwith.com/blog/?p=53

如果您喜欢编码到“解决方法”,那么,当然,Hibernate适合您。如果你喜欢干净、纯粹、面向对象、模型驱动的开发,你把所有的时间都花在建模、设计和编码上,而没有一个花在丑陋的解决方法上,那么花几个小时来评估JDO/DataNucleus。投入的时间将偿还一千倍。

2017年2月更新

很长一段时间以来,DataNucleus除了JDO持久性标准之外还实现了JPA持久性标准,因此将现有的JPA项目从Hibernate移植到DataNucleus应该非常简单,您可以通过非常少的代码更改(如果有的话)获得DataNucleus的所有上述好处。所以就问题而言,选择特定标准,JPA(仅限RDBMS)与JDO(RDBMS +No SQL + ODBMSes +其他),DataNucleus支持两者,Hibernate仅限于JPA。

休眠数据库更新的性能

选择ORM时要考虑的另一个问题是其脏检查机制的效率 - 当它需要构造SQL来更新当前事务中已更改的对象时,这变得非常重要 - 特别是当有很多对象时。在这个SO答案中有一个关于Hibernate的肮脏检查机制的详细技术描述:带有HIBERNATE插入非常慢的JPA。


推荐