Hibernate vs JPA vs JDO - 各自的优缺点?[关闭]

IT小君   2021-11-05T01:17:01

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

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

我很难说出 JPA 规范、您从 Hibernate 库本身获得的内容以及 JDO 必须提供的内容之间的区别。

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

  • 各自的优缺点是什么?
  • 你会为一个新项目推荐哪个?
  • 在某些情况下,使用一种框架与另一种框架是否有意义?
评论(11)
IT小君

一些注意事项:

  • JDO 和 JPA 都是规范,而不是实现。
  • 这个想法是你可以交换 JPA 实现,如果你限制你的代码只使用标准 JPA。(JDO 同上。)
  • Hibernate 可以用作 JPA 的一种此类实现。
  • 然而,Hibernate 提供了一个原生 API,其功能超出了 JPA。

海事组织,我会推荐休眠。


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

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

  • 如果您担心供应商搭售的前景,并且在不求助于供应商特定扩展的情况下无法使用 JPA,那么请不要使用 JPA。(JDO 同上)。

在现实中,你可能需要权衡多少你被厂商担心搭配与多少,你需要这些供应商特定的扩展。

还有其他因素,例如您/您的员工对各自技术的了解程度,产品的许可费用是多少,以及您相信谁的故事关于 JDO 和 JPA 未来会发生什么。

2021-11-05T01:17:01   回复
IT小君

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

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

您可能会发现 Hibernate 令人讨厌的另一件事是,您必须引用您认为是对象的内容……它通常是对象的“代理”。如果没有字节码增强的好处,代理模式需要允许按需加载(即避免在拉入顶级对象时拉入整个对象图)。准备好覆盖 equals 和 hashcode,因为您认为您引用的对象通常只是该对象的代理。

下面是一个使用 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 月更新

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

Hibernate DB 更新的性能

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

2021-11-05T01:17:02   回复
IT小君

我最近评估并选择了一个 Java 项目的持久性框架,我的发现如下:

我所看到的是,对JDO的支持主要是:

  • 您可以使用非 sql 数据源、db4o、hbase、ldap、bigtable、couchdb(cassandra 插件)等。
  • 您可以轻松地从 sql 切换到非 sql 数据源,反之亦然。
  • 没有代理对象,因此减少了 hashcode() 和 equals() 实现的痛苦
  • 更多的 POJO,因此需要更少的解决方法
  • 支持更多的关系和字段类型

支持JPA的主要是:

  • 更流行
  • jdo死了
  • 不使用字节码增强

我看到很多来自 JPA 开发人员的亲 JPA 帖子,他们显然没有使用 JDO/Datanucleus,为不使用 JDO 提供了弱论据。

我还看到很多来自 JDO 用户的帖子,他们迁移到 JDO 并因此感到更加快乐。

关于 JPA 更受欢迎,这似乎部分是由于 RDBMS 供应商的支持,而不是技术上的优越。(对我来说听起来像 VHS/Betamax)。

JDO 及其参考实现 Datanucleus 显然还没有消亡,正如 Google 将其用于 GAE 并积极开发源代码 (http://sourceforge.net/projects/datanucleus/) 所表明的那样。

由于字节码增强,我看到了许多关于 JDO 的抱怨,但还没有解释为什么它很糟糕。

事实上,在一个越来越沉迷于 NoSQL 解决方案的世界里,JDO(和 datanucleus 实现)似乎是一个更安全的赌注。

我刚刚开始使用 JDO/Datanucleus 并对其进行了设置,以便我可以在使用 db4o 和 mysql 之间轻松切换。使用 db4o 有助于快速开发,而不必过多担心 DB 模式,然后,一旦模式稳定即可部署到数据库。我也有信心,以后我可以将我的应用程序的全部/部分部署到 GAE 或利用分布式存储/map-reduce a la hbase /hadoop / cassandra,而无需进行太多重构。

我发现开始使用 Datanucleus 的最初障碍有点棘手 - datanucleus 网站上的文档有点难以进入 - 教程并不像我希望的那样容易理解。话虽如此,一旦您过了最初的学习曲线,关于 API 和映射的更详细的文档是非常好的。

答案是,这取决于你想要什么。我宁愿拥有更简洁的代码、无供应商锁定、更面向 pojo、nosql 选项和更受欢迎的内容。

如果您想要与大多数其他开发人员/绵羊一样的温暖挑剔感觉,请选择 JPA/hibernate。如果您想在自己的领域处于领先地位,请试驾 JDO/Datanucleus 并下定决心。

2021-11-05T01:17:02   回复
IT小君

你会为一个新项目推荐哪个?

我不建议!将 Spring DAOJdbcTemplateStoredProcedure,RowMapper一起使用RowCallbackHandler

我个人使用 Hibernate 的经验是,预先节省的时间远远被您花费在尝试理解和调试问题(例如意外的级联更新行为)上的无休止的时间所抵消。

如果您使用的是关系数据库,那么您的代码越接近它,您拥有的控制权就越多。Spring 的 DAO 层允许对映射层进行精细控制,同时消除对样板代码的需要。此外,它集成到 Spring 的事务层中,这意味着您可以非常轻松地添加(通过 AOP)复杂的事务行为,而不会干扰您的代码(当然,您也可以通过 Hibernate 获得这一点)。

2021-11-05T01:17:02   回复
IT小君

JDO死了

JDO 实际上并没有死,所以请检查你的事实。JDO 2.2 于 2008 年 10 月发布 JDO 2.3 正在开发中。

这是在 Apache 下公开开发的。比 JPA 有更多的版本,它的 ORM 规范仍然领先于 JPA2 提出的特性

2021-11-05T01:17:02   回复
IT小君

JDO 具有比 JPA 先进的功能,请参阅http://db.apache.org/jdo/jdo_v_jpa.html

2021-11-05T01:17:03   回复
IT小君

我正在使用 JPA(来自 Apache 的 OpenJPA 实现,它基于 KODO JDO 代码库,该代码库已有 5 年以上的历史并且非常快速/可靠)。恕我直言,任何告诉你绕过规范的人都在给你不好的建议。我投入了时间,肯定得到了回报。使用 JDO 或 JPA,您可以以最少的更改更改供应商(JPA 具有 orm 映射,因此我们在不到一天的时间内讨论可能更改供应商)。如果你像我一样有 100 多张桌子,那就太棒了。此外,您可以通过集群缓存逐出获得内置缓存,这一切都很好。SQL/Jdbc 适用于高性能查询,但透明持久性对于编写算法和数据输入例程要好得多。我的整个系统中只有大约 16 个 SQL 查询(5 万多行代码)。

2021-11-05T01:17:03   回复
IT小君

我自己一直在研究这个问题,但找不到两者之间的明显区别。我认为最大的选择是您使用哪种实现。对于我自己,我一直在考虑DataNucleus平台,因为它是两者的数据存储不可知实现。

2021-11-05T01:17:03   回复
IT小君

任何说 JDO 已死的人都是 FUD 的大贩子,他们知道这一点。

JDO 还活着。该规范仍然比年轻得多且受约束的 JPA 更强大、更成熟和更先进。

如果您只想将自己限制在 JPA 标准中可用的内容,您可以写入 JPA 并将 DataNucleus 用作高性能、比 JPA 的其他实现更透明的持久性实现。当然,如果您想要 JDO 带来的建模的灵活性和效率,DataNucleus 也实现了 JDO 标准。

2021-11-05T01:17:04   回复
IT小君

我在同一个项目中使用了 Hibernate(JPA 实现)和 JPOX(JDO 实现)。JPOX 工作正常,但很快就遇到了错误,当时它不支持某些 Java 5 语言功能。它在处理 XA 事务时遇到了问题。我正在从 JDO 对象生成数据库模式。它每次都想连接到数据库,如果您的 Oracle 连接不工作,这很烦人。

然后我们切换到 Hibernate。我们暂时只使用纯 JPA,但我们需要使用一些 Hibernate 特定功能来进行映射。在多个数据库上运行相同的代码非常容易。Hibernate 似乎积极地缓存对象,或者有时只是有奇怪的缓存行为。有一些 DDL 构造 Hibernate 无法处理,因此它们在运行以初始化数据库的附加文件中定义。当我遇到 Hibernate 问题时,通常会有很多人遇到同样的问题,这使得在谷歌上搜索解决方案变得更容易。最后,Hibernate 似乎设计良好且可靠。

其他一些响应者建议只使用 SQL。对象关系映射的真正杀手级用例是测试和开发。为处理大量数据而构建的数据库通常很昂贵,或者很难安装。它们很难测试。有很多内存 Java 数据库可用于测试,但通常对生产无用。能够使用真实但有限的数据库将提高开发效率和代码可靠性。

2021-11-05T01:17:04   回复
IT小君

我在 2012 年 5 月制作了一个使用 JDO 3.0 和 DataNucleus 3.0 的示例 WebApp - 看看它有多干净:https : //github.com/TorbenVesterager/BadAssWebApp

好吧,也许它有点太干净了,因为我将 POJO 用于数据库和 JSON 客户端,但这很有趣 :)

PS:包含一些 SuppressWarnings 注释(在 IntelliJ 11 中开发)

2021-11-05T01:17:04   回复