让我来尝试一下。首先,我写了一些关于这个主题的文章使用 ORM 还是普通 SQL? https://stackoverflow.com/questions/494816/using-an-orm-or-plain-sql/494853#494853。具体针对您的观点:
学习曲线/易用性
Ibatis 是关于 SQL 的。如果您了解 SQL,那么 ibatis 的学习曲线就很简单。 Ibatis 在 SQL 之上做一些事情,例如:
您仍然需要学习,但最大的障碍是 SQL。
另一方面,JPA(包括 Hibernate)试图与 SQL 保持距离,并以对象而不是关系的方式呈现事物。然而,正如乔尔指出的那样,抽象存在漏洞 http://www.joelonsoftware.com/articles/LeakyAbstractions.htmlJPA 也不例外。要进行 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?嗯,这是一个问题。