让我来分析一下。首先,我在Using an ORM or plain SQL? 中写了一些关于这个主题的文章。专门针对您的观点:
学习曲线/易用性
Ibatis 是关于 SQL 的。如果您了解 SQL,则 ibatis 的学习曲线很简单。 Ibatis 在 SQL 之上做了一些事情,例如:
您仍然需要学习,但最大的障碍是 SQL。
另一方面,JPA(包括 Hibernate)试图与 SQL 保持距离,并以对象而不是关系的方式呈现事物。然而,正如 Joel 指出的那样,abstractions are leaky 和 JPA 也不例外。要进行 JPA,您仍然需要了解关系模型、SQL、查询的性能调整等等。
Ibatis 只会让您应用您知道或正在学习的 SQL,而 JPA 将要求您了解其他内容:如何配置它(XML 或注释)。我的意思是弄清楚外键关系是某种类型的关系(一对一、一对多或多对多)、类型映射等。
如果您了解 SQL,我会说学习 JPA 的障碍实际上更高。如果你不这样做,那么 JPA 的结果就是混合的结果,它允许你有效地推迟学习 SQL 一段时间(但它不会无限期地推迟它)。
使用 JPA,一旦您设置了实体及其关系,其他开发人员就可以简单地使用它们,而无需学习有关配置 JPA 的所有内容。这可能是一个优势,但开发人员仍然需要了解实体管理器、事务管理、托管对象与非托管对象等等。
值得注意的是,JPA 也有自己的查询语言 (JPA-SQL),无论您是否了解 SQL,都需要学习它。您会发现 JPA-SQL 不能做 SQL 可以做的事情的情况。
生产力
这很难判断。就我个人而言,我认为我在 ibatis 中的工作效率更高,但我对 SQL 也很满意。有些人会争辩说他们使用 Hibernate 的效率更高,但这可能是由于(至少部分是)不熟悉 SQL。
此外,JPA 的生产力具有欺骗性,因为您偶尔会遇到数据模型或查询的问题,当您打开日志记录并查看您的 JPA 提供程序正在生成的 SQL 时,您需要花费半天到一天的时间来解决然后计算出设置和调用的组合,让它产生既正确又高效的东西。
您在使用 Ibatis 时不会遇到这种问题,因为您自己编写了 SQL。您可以通过在 PL/SQL Developer、SQL Server Management Studio、Navicat for MySQL 或其他任何工具中运行 SQL 来测试它。查询正确后,您所做的就是映射输入和输出。
我还发现 JPA-QL 比纯 SQL 更尴尬。您需要单独的工具来运行 JPA-QL 查询以查看结果,这是您必须学习的更多内容。我实际上发现 JPA 的整个部分都相当笨拙和笨拙,尽管有些人喜欢它。
可维护性/稳定性
Ibatis 的危险在于扩散,这意味着您的开发团队可能只是在需要时不断添加值对象和查询,而不是寻求重用,而 JPA 每个表都有一个实体,一旦您拥有该实体,就是这样。命名查询倾向于在该实体上进行,因此很难错过。临时查询仍然可以重复,但我认为这不是一个潜在的问题。
然而,这是以僵化为代价的。通常在应用程序中,您需要来自不同表的点点滴滴的数据。使用 SQL 很容易,因为您可以编写单个查询(或少量查询)以一次性获取所有数据并将其放入自定义值对象中。
使用 JPA,您可以将该逻辑向上移动到您的业务层。实体基本上全有或全无。现在严格来说这不是真的。各种 JPA 提供程序将允许您部分加载实体等,但即使在那里您谈论的是相同的离散实体。如果您需要来自 4 个表的数据,您要么需要 4 个实体,要么需要将所需的数据组合到业务或表示层中的某种自定义值对象中。
我喜欢 ibatis 的另一件事是您的所有 SQL 都是外部的(在 XML 文件中)。有些人会认为这是一个缺点,但我不是。然后,您可以通过搜索 XML 文件相对容易地找到表和/或列的用途。将 SQL 嵌入代码中(或者根本没有 SQL 的地方)可能会更难找到。您还可以将 SQL 剪切并粘贴到数据库工具中并运行它。这些年来这对我有用了多少次,我怎么夸大都不为过。
性能/可扩展性
在这里,我认为 ibatis 胜出。它是直接的 SQL 和低成本。从本质上讲,JPA 根本无法管理相同级别的延迟或吞吐量。现在 JPA 的目标是延迟和吞吐量很少出现问题。然而,高性能系统确实存在,并且倾向于不喜欢 JPA 等更重量级的解决方案。
加上使用 ibatis,您可以编写一个查询,该查询使用您需要的确切列准确返回您想要的数据。从根本上说,JPA 在返回离散实体时无法击败(甚至匹敌)它。
易于故障排除
我认为这也是 Ibatis 的胜利。就像我上面提到的,使用 JPA,您有时会花费半天时间来获取查询或实体生成您想要的 SQL,或者诊断事务失败的问题,因为实体管理器试图持久化非托管对象(可能是批处理的一部分)您已经投入了大量工作的工作,因此可能很难找到)。
如果您尝试使用不存在的表或列,它们都会失败,这很好。
其他标准
现在您没有提到可移植性是您的要求之一(意味着在数据库供应商之间移动)。值得注意的是,这里 JPA 有优势。注释的可移植性不如 Hibernate XML(例如标准 JPA 注释没有 Hibernate 的“本机”ID 类型的等效项),但它们都比 ibatis / SQL 更可移植。
我还看到 JPA / Hibernate 用作可移植 DDL 的一种形式,这意味着您运行一个小型 Java 程序,该程序从 JPA 配置创建数据库模式。使用 ibatis,您需要为每个受支持的数据库创建一个脚本。
可移植性的缺点是 JPA 在某些方面是最小的公分母,这意味着支持的行为在很大程度上是广泛的数据库供应商所支持的常见行为。如果你想在 ibatis 中使用 Oracle Analytics,没问题。在 JPA 中?嗯,这是个问题。