Hibernate,iBatis,Java EE或其他Java ORM工具

我们正在规划一个大型企业应用程序。 在经历了J2EE的痛苦之后,我们将重点放在评估hibernate上。

它看起来像新的Java EE API更简单。 我还读了一些关于Hibernate和iBatis的好消息。 我们的团队对于任何框架都没有什么经验。

有5个主要的比较点我想确定

  • 学习曲线/易用性
  • 生产率
  • 可维护性/稳定性
  • 性能/可扩展性
  • 易于排除故障

如果您要pipe理一个具有J2EE经验的开发人员团队,您将使用哪种ORM工具,为什么?

让我对此做一个解释。 首先,我在使用ORM或纯SQL中写了一些关于这个主题的内容? 。 特别要说明你的观点:

学习曲线/易用性

Ibatis是关于SQL的。 如果你知道SQL,ibatis的学习曲线是微不足道的。 Ibatis在SQL之上做了一些事情,比如:

  • 通过…分组;
  • 歧视types; 和
  • dynamicSQL。

你仍然需要学习,但最大的障碍是SQL。

另一方面,JPA(包括Hibernate)试图与SQL保持距离,以事物而不是关系的方式呈现。 正如Joel指出的那样, 抽象是有漏洞的 ,JPA也不例外。 要做JPA,你仍然需要了解关系模型,SQL,查询的性能调优等等。

鉴于Ibatis只需要应用您所知道或正在学习的SQL,JPA就会要求您知道其他内容:如何configuration它(XML或注释)。 我的意思是指明外键关系是某种关系(一对一,一对多或多对多),types映射等等。

如果你知道SQL,我会说学习JPA的障碍实际上更高。 如果你不这样做,那么JPA允许你在一段时间内有效推迟学习SQL(但并不是无限期地放弃它)。

使用JPA一旦你设置了你的实体和他们的关系,那么其他开发者就可以简单地使用它们,而不需要学习关于configurationJPA的一切。 这可能是一个优势,但开发人员仍需要了解实体pipe理器,事务pipe理,托pipe与非托pipe对象等。

值得注意的是,JPA也有自己的查询语言(JPA-SQL),你需要知道你是否知道SQL。 你会发现JPA-SQL不能完成SQL所能做的事情。

生产率

这是一个难以判断的问题。 就我个人而言,我认为我在ibatis中的工作效率更高,但是我也非常适合使用SQL。 有些人会认为他们在Hibernate方面的工作效率更高,但这可能是由于不熟悉SQL所致。

另外JPA的生产力是欺骗性的,因为偶尔会遇到一个数据模型或查询的问题,需要你半天到一天的时间来解决,因为你打开日志logging,并观察你的JPA提供程序正在生产什么SQL,然后工作把设置和调用结合起来,让它产生正确和高性能的东西。

你只是没有Ibatis的这种问题,因为你自己写了SQL。 你可以通过在PL / SQL Developer,SQL Server Management Studio,Navicat for MySQL或其他方式下运行SQL来testing它。 查询正确后,您所做的只是映射input和输出。

另外我发现JPA-QL比纯SQL更笨拙。 您需要单独的工具才能运行JPA-QL查询来查看结果,这是您必须学习的东西。 实际上,我发现JPA的整个部分相当尴尬和笨拙,虽然有些人喜欢它。

可维护性/稳定性

Ibatis在这里面临的危险是扩散意味着你的开发团队可能只是在需要的时候继续添加价值对象和查询,而不是寻找重用,而JPA每个表有一个实体,一旦拥有那个实体,就是这样。 被命名的查询往往在那个实体上,所以很难错过。 临时查询仍然可以重复,但我认为这是一个潜在的问题。

这是以牺牲刚性为代价的。 通常在应用程序中,您将需要来自不同表格的数据。 使用SQL很容易,因为您可以编写单个查询(或less量查询)来获取所有数据,并将其放入自定义值对象中。

使用JPA,您正在将这一逻辑转移到您的业务层。 实体基本上是全部或没有。 现在这不是严格的。 各种JPA提供商将允许您部分加载实体等,但即使在那里,您也在谈论相同的离散实体。 如果您需要来自4个表格的数据,则您需要4个实体,或者您需要将所需的数据合并到业务或表示层中的某种自定义值对象中。

我喜欢关于ibatis的另一件事是所有的SQL都是外部的(在XML文件中)。 有人会说这是一个劣势,但不是我。 然后,您可以通过searchXML文件来相对容易地find表格和/或列的使用。 将SQLembedded到代码中(或者根本没有SQL),可能会很难find。 您也可以将SQL剪切并粘贴到数据库工具中并运行它。 我不能夸大多less次这对我多年来有用。

性能/可扩展性

在这里,我认为伊巴蒂斯获胜。 这是直接的SQL和低成本。 就其性质而言,JPA根本无法pipe理相同级别的延迟或吞吐量。 现在JPA要做的是延迟和吞吐量只是很less的问题。 然而,高性能系统确实存在,并且倾向于不利于像JPA这样的更重量级的解决scheme。

再加上ibatis,你可以编写一个查询,用你需要的确切列来返回你想要的数据。 从根本上来说,JPA在返回离散实体时无法击败(甚至无法匹配)。

易于排除故障

我认为这也是Ibatis的一个胜利。 就像我上面提到的那样,使用JPA,有时你会花费半天的时间获得一个查询或实体产生你想要的SQL,或者在事务失败的时候诊断一个问题,因为实体pipe理器试图持久化一个非托pipe对象(这可能是批处理的一部分工作,你做了很多工作,所以它可能是不平凡的发现)。

如果您尝试使用不存在的表或列,这两者都会失败,这很好。

其他标准

现在你没有提到可移植性作为你的一个要求(意味着在数据库供应商之间移动)。 值得注意的是,JPA在这里有优势。 注释不如Hibernate XML可移植(例如,标准的JPA注释没有Hibernate的“native”IDtypes),但两者比ibatis / SQL更具可移植性。

另外,我还看到JPA / Hibernate用作可移植DDL的一种forms,这意味着您运行一个小型的Java程序,从JPAconfiguration创build数据库模式。 使用ibatis,您需要为每个支持的数据库提供一个脚本。

可移植性的缺点在于,JPA在某些方面是最低的共同标准,这意味着支持的行为在很大程度上是广泛的数据库供应商共同支持的行为。 如果您想在ibatis中使用Oracle Analytics,则没有问题。 在JPA? 那么,这是一个问题。

iBatis和Hibernate之间的一个简单的经验法则是,如果你想要更多的SQL /关系视图的世界,iBatis更适合; 而对于更复杂的inheritance链,对于SQL,Hibernate的直接看法较less。 两者都是广泛使用和坚实的良好框架。 所以我觉得两者都可能运作良好。 也许读两个教程,看看是否听起来比另一个更好,只要select一个。

你列出的东西,我不认为性能是非常不同的 – 瓶颈将几乎总是数据库,而不是框架。 对于其他的事情,我认为不同的开发人员会更喜欢一个或另一个,即没有普遍接受的优先级(对于iBatis VS Hibernate)。

您使用哪种解决scheme还取决于您select(或需要)符合Java EE规范的遵从性。 JPA是Java EE系统中数据访问的“标准”,所以如果你特别要坚持这一点,就应该使用它(有一些注意事项)。

JPA是对象关系映射系统的标准化。 因此,它不提供一个实现,它只是定义一个标准化的方法。 Hibernate Entity Manager就是这样一个实现。

由于JPA是跨多个供应商的标准,并且由于它还是相当新的,所以它缺less一些在一些使用情况下(例如,用于生成dynamicSQL的Criteria API)有价值的更深奥的function。 如果您在需要直接使用Hibernate,甚至直接使用JDBC的情况下使用JPA计划。 对于这样的情况,一个通用的DAO模式是非常有用的; 你可以修改这个:用于JPA和JDBC的通用数据访问对象很容易。

JPA有一些困难的限制(特别是如果你习惯于Hibernate),并且对你更加习惯于直接编写JDBC的开发人员来说很难实施。 如果您将此视为一种方法,请务必做好关于ORM与JDBC的优点与缺点的作业。

如果你使用JPA,一旦你达到了学习曲线,它将取决于简单的开发(特别是如果你正确实现上述的DAO模式),而且在获取查询结果的多层caching。 如果做得很好(一个大“如果”,我知道),我看到这提供了英俊的好处。

最后,如果你有一个传统的数据模型,你几乎没有灵活性,Hibernate(和JPA)会给你更多的麻烦,也许值得。 例如:

  • 如果数据库没有候选主键(对于有效的hashCode&equals实现),您将需要对哪些列进行唯一的定义 – 也许是简单的,也许是复杂的,取决于您的模式的复杂性,
  • 如果您无法添加版本或时间戳列,那么您将失去Hibernate执行乐观locking的能力,并且最终不得不在更新之前进行查询。

(在第一条评论中添加)如果你足够幸运重新devise你的数据库,如果你打算使用ORM,那么需要考虑两点:

  • 为所有相关表添加版本号列以支持乐观locking。
  • 在您的数据分析过程中,决定开发人员应该使用hashCode()equals()不可为空的“ 备用密钥 ”列。 在这些方法中不要使用PK列。

要添加另一个选项到列表中…看看:

Ebean ORM(www.avaje.org)。

这主要是比JPA或Hibernate更简单,更直观的编程模型。 具体而言,它没有Hibernate Session或JPA EntityManager,没有分离/附加对象(不合并,持久化,刷新),延迟加载正常。

…更简单的使用和理解。

你也可以使用你自己的SQL与Ebean(查询,更新,存储过程)和IMO匹配Ibatis易于使用和你自己的SQL使用。

如果你正在使用Java SE中的ORM,那么我build议你检查一下。

  • LGPL许可证
  • 使用JPA批注进行映射(@Entity,@OneToMany等)
  • 无需会话的API(不合并,坚持,刷新… save()和delete())
  • “部分对象”支持
  • 大型查询支持(每个对象图持久性上下文)
  • 后台查询
  • 良好的批量处理支持
  • 自动查询调整(通过“自动提取”)

干杯,罗伯。

目前我们正在开发一个同时使用Hibernate和ibatis的项目。 为什么要使用hibernate? 它支持我们的领域模型,关系和inheritance。 我们有一个非常复杂的域模型,Hiberante支持它。 无需担心写入插入,更新等。Ibatis仅用于查看。 有查询,我们有查询与查询映射的对象(类似于域模型,但不是域模型)。 Ibatis返回所需的视图中的数据,而不用担心从结果集中读取,而这些结果集必须在Spring JDBC中pipe理。 为什么我们不使用HQl或Spring JDBC? 这个域非常复杂,在渲染视图的时候,我们做了计算,分组和大量的本地SQL函数。 我们在查询中执行所有这些操作,使用dynamic查询,pipe理ibatis中的条件并获得一个干净的轻量级对象。 更有意义的是,如果你必须遍历多个层来获取冬眠的数据所以根据你的情况,你可能只想使用一个,两个或可能是没有。 但是,绝对的,hibernate不是你不能没有的东西。

请注意,在非平凡的multithreading应用程序中使用JPA / Hibernate(以及可能是大多数其他ORM解决scheme)可以快速成为真正的PITA,因为数据库会话只需限制在一个线程(Session对象不是线程安全的)。 添加延迟加载和持久化实体最多只能属于一个活动会话的事实…而且你正处于一个匆忙之中……

你可能想看看在multithreading* Swing应用程序中使用Hibernate的会话pipe理 (或者只是search'hibernatemultithreading')。

我的经验法则(YMMV):如果应用程序不适合某种请求/响应循环(比如web服务),那么使用其他方法可能会更好。

当然,另一个解决scheme是以避开上述框架限制的方式来devise应用程序。 改变一个应用程序的devise,所以我可以让框架XYZ工作留下一个坏回味。

无论如何,只有我的$ 0.02

我认为我们应该考虑到我们使用Java(或OO)的主要原因。

该系统必须灵活,并允许对规范进行不断的修改(这在现实生活中经常发生)。 否则,我们应该用C编程,因为速度要快很多。

我认为Web应用程序的最佳堆栈是Java EE:JPA – EJB – JSF(扩展的持久化上下文对话范围)。

JSF也比纯JSP / Servlet慢,但开发速度更快。

JPA很难学,但开发速度更快(你知道:RAD),并且变化没有太大的(容易出错的复制粘贴)影响。 在您最常用的实体中添加一个新列,您将不得不更新iBatis中的所有语句…

JPA在所有情况下都不能很好地工作,但它覆盖了大部分情况,而且它也允许您插入Native Query而不是JPQL而不更改任何代码。 但是如果你发现自己编写了太多的Native Query,你的项目可能会更适合iBatis。

至于性能方面,如果你知道事情如何转化为SQL,并且如果你把它做到最好,那么如果你把它做成不适合自己的东西的话,JPA也会是高性能的,它会产生太多的查询。 没有魔法! 你必须意识到生成的查询,而不是盲目地希望你可以采取简单的方法,当一些复杂的情况下可能会出现。

同样,如果开发人员具有SQL的所有function,他们将编写太复杂的查询来处理业务逻辑,而不是集中在一起,您将在SQL中拥有一些业务逻辑,而在EJB中则拥有一些业务逻辑。 JPA应该坚持你的模式,而不是为了业务逻辑。

标准查询也不适合构build安全的nomatterhow复杂的dynamic查询。

如果你确实有一个绿地项目,你可以使用hibernate,但要注意学习曲线非常陡峭。

如果你有一个现有的数据库,你可以更好地使用iBatis,因为有一天你会很有成效,而且在两天之后你就可以知道这一切。

有一件事你必须考虑的是,hibernate标准API是非常适合创build自定义查询,这取决于您的应用程序,可能是一个很好的理由。

如果你没有一个好的对象模型,我没有看到Hibernate的好处。 你当然有ORM中的“关系”,因为你有一个关系数据库,但“对象”是关键。 没有对象,没有ORM。 我认为对象和表之间的1:1映射,没有更丰富的对象行为,不合理的ORM。 坚持与JDBC或iBatis,如果这是你的情况。

我build议与JPA一起,并且(取决于你的项目的持续时间/范围),你可能会考虑JPA2,因为它提供了一些JPA(例如一个非常漂亮的查询API)缺失的function。

去hibernate。 之后你的项目肯定会变得越来越大,投资(在学习hibernate)将会以某种方式得到回报。

在决定使用哪一个之前,您是否尝试过使用ORM工具来回答问题? 如果您的团队中的人员知道SQL,请参阅JDBC。