比较ORM工具

发布者    |       Hibernate ORM

在过去的三周里,我看到了三四个 ORM工具比较;在一些博客中,在我们的论坛上,我甚至参与了几次决策。

我有这样的印象,许多开发者在分类和评估ORM工具时都有问题,无论是Hibernate、Cayenne、PrIdE(我希望拼写是正确的),还是一些自制的JDBC框架。我确实在某一点上感到非常沮丧,但让我写这篇博客的可能是今天由Scott Ferguson发表的一篇文章。他比较了EJB CMP、JDO和Hibernate。我并不满意他的论点列表。不要误会,我并不是在抱怨Scott的结论(我们宝贵的Hibernate!),事实上,我通常都会听Scott的。我曾经甚至密切关注Resins的开发好几年,几乎为中型安装获得批准(政治...),甚至报告并修复了一些错误。

所以,这篇博客,在长篇引言之后,是关于 比较ORM解决方案 的。所有这些评论和文章的共同点是一个非常模糊的评判标准。在一篇文章中,我看到有人比较了 加载和保存单个对象,并观察了执行此操作所需的代码行数。接下来,我们听到类似 我的ORM应该与对象一起工作 或其他模糊的声明,在实践中可能无法帮助你决定使用什么。

我为《Hibernate实战》做了研究,我认为我们为ORM解决方案找到了一个非常好的分类法。实际上,Mark Fussel 从1997年开始使用这些类别,我们只是重写了他的列表,并将其置于Java应用程序开发的上下文中。

纯关系型

整个应用程序,包括用户界面,都是围绕关系模型和基于SQL的关系操作设计的。直接SQL可以在各个方面进行微调,但缺点,如难以维护、缺乏可移植性和可维护性,是显著的,尤其是在长期运行中。这类应用程序通常大量使用存储过程,将一些工作从业务层移至数据库。

轻量级对象映射

实体被表示为类,这些类手动映射到关系表中。使用知名设计模式(如DAO)隐藏了手写的SQL/JDBC,以从业务逻辑中分离。这种方法极其普遍,对于具有少量实体或具有通用、元数据驱动的数据模型的应用程序非常成功。在这种类型的应用程序中,存储过程可能有其位置。

中量级对象映射

应用程序是围绕对象模型设计的。SQL在构建时使用代码生成工具生成,或在运行时由框架代码生成。对象之间的关系由持久化机制支持,可以使用面向对象的表达语言指定查询。对象由持久化层缓存。许多ORM产品和自建的持久化层至少支持这一级别的功能。它非常适合具有一些复杂事务的中型应用程序,尤其是在数据库产品之间可移植性很重要的情况下。这些应用程序通常不使用存储过程。

完全对象映射

完全对象映射支持复杂的对象建模:组合、继承、多态以及“通过可达性”的持久化或更灵活的传递性持久化解决方案。持久化层实现透明持久化;持久化类不继承任何特殊基类,也不需要实现特殊接口。持久化层不对领域模型实现强制特定的编程模型。透明地实现了高效获取策略(延迟和预先获取)和缓存策略。这一级别的功能很难通过自建的持久化层实现——它相当于数月或数年的开发时间。

根据我的经验,很容易为给定产品找到其类别。在《Hibernate in Action》中,我们还列出了一些你应该在比较ORM工具时提出的问题。

  • 持久化类是什么样的?它们是细粒度的JavaBeans吗?
  • 映射元数据是如何定义的?
  • 我们应该如何映射类继承层次结构?
  • 持久化逻辑在运行时如何与业务域的对象交互?
  • 持久化对象的生命周期是什么?
  • 提供了哪些排序、搜索和聚合功能?
  • 我们如何有效地检索具有关联的数据?

此外,任何数据访问技术都存在两个常见问题。它们也对ORM的设计和架构施加了基本约束。

  • 事务和并发
  • 缓存管理(和并发)

找到这些问题的答案,你就可以比较ORM软件。Scott实际上是从“生命周期”开始的,但他在文章中提供的信息不足以进行真正的讨论,这主要是他的观点(这在博客上是可以的)。

生活中总是有许多解决方案,没有单一的产品、项目或规范能在所有场景下都是完美的。你不必试图达到列表的“顶端”,总是使用完全对象映射(以及相应的工具)。在某些情况下,使用轻量级对象映射工具(例如iBatis)有非常好的理由!在许多情况下,JDBC和SQL是最好的选择。我正在谈论同一级别的比较,我上面提到的类别和问题已经让我有了很好的经验。阅读这本书吧。:)

感谢您的聆听


返回顶部