ORM技术与JDBC相比有何优劣之处?

25
我的问题涉及ORM和JDBC技术,您会基于什么标准决定使用ORM技术还是JDBC技术或者其他方式?
谢谢。
4个回答

18

JDBC

  1. 使用JDBC时,开发人员需要编写代码来将对象模型的数据表示映射到关系数据模型和相应的数据库架构。
  2. 使用JDBC时,Java对象与数据库表之间的自动映射以及相反的转换需要开发人员手动编写代码进行处理。
  3. JDBC仅支持本地结构化查询语言(SQL)。开发人员必须找出访问数据库的有效方法,即从多个查询中选择有效的查询以执行相同的任务。
  4. 使用JDBC处理持久数据(数据库表)的应用程序具有大量特定于数据库的代码。编写的代码实际上是将表数据映射到应用程序对象和相反的过程,也就是将表字段映射到对象属性。由于表或数据库更改,因此必须更改对象结构以及更改用于映射表到对象/对象到表的代码。
  5. 使用JDBC时,开发人员需要手动处理JDBC结果集并通过代码将其转换为Java对象,以在应用程序中使用这些持久数据。因此,在JDBC中,Java对象和数据库表之间的映射是手动完成的。
  6. 在JDBC中,缓存由手动编码维护。
  7. 在JDBC中,没有检查每个用户是否始终具有更新的数据。开发人员必须添加此检查。

Hibernate

  1. Hibernate是一种灵活且强大的ORM解决方案,用于将Java类映射到数据库表。Hibernate本身使用XML文件处理映射,因此开发人员不需要编写代码来处理此过程。
  2. Hibernate提供透明持久性,开发人员不需要显式编写代码,将数据库表元组映射到与RDBMS交互期间的应用程序对象。
  3. Hibernate提供了一个强大的查询语言Hibernate Query Language(独立于数据库类型),其语法类似于SQL,并包括对多态查询的完全支持。Hibernate还支持原生SQL语句。它还为应用程序选择执行数据库操作任务的有效方法。
  4. Hibernate自己提供了这个映射。表和应用程序对象之间的实际映射在XML文件中完成。如果数据库或任何表发生更改,则只需更改XML文件属性即可。
  • Hibernate通过自己维护对象-表映射来减少代码行数,并以Java对象的形式将结果返回给应用程序。它解除了程序员手动处理持久数据的负担,从而缩短了开发时间和维护成本。
  • 在透明持久性下,Hibernate将缓存设置为应用程序工作空间。由于查询的结果,关系元组被移动到此缓存中。如果客户应用程序为同一写入多次读取相同的数据,则会提高性能。自动透明持久性允许开发人员更专注于业务逻辑而不是应用程序代码。
  • Hibernate使开发人员能够向应用程序定义版本类型字段。由于这个字段的存在,每当关系元组以Java类对象的形式更新到数据库表中时,Hibernate就会更新数据库表的版本字段。因此,如果两个用户检索相同的元组并对其进行修改,其中一个用户将修改后的元组保存到数据库中,则Hibernate会自动为该元组更新版本。当另一个用户试图保存更新后的元组到数据库时,它不允许保存它,因为此用户没有更新的数据。

  • 16

    复杂性。

    ORM如果您的应用程序是面向领域的,对象之间的关系很复杂,或者您需要让该对象定义应用程序的功能。

    JDBC / SQL 如果您的应用程序足够简单,只需直接从数据库中提供数据,或者它们之间的关系足够简单。

    Martin Fowler的书“企业应用架构模式”更好地解释了这两种类型之间的区别:

    参见:领域模型事务脚本


    1
    我的理解是,你必须要有一种感觉,知道ORM的高昂成本何时能够得到回报。 - Jonathan Feinberg
    1
    我必须同意这一点 - 但我还要补充说,在某些情况下,在单个应用程序中同时使用两者是有意义的。 - Chris R
    如果你的应用程序非常复杂,需要使用ORM,那么架构师真的应该质疑是否有更好的方式来分解应用程序(提示:微服务)。 - Sridhar Sarnobat

    4
    我想你忘了看“功能关系映射”。
    总结一下:
    - 如果您想专注于数据结构,请使用ORM,如JPA / Hibernate。 - 如果您想突出治疗效果,请查看FRM库:QueryDSL或Jooq。 - 如果您需要针对特定数据库调整SQL请求,请使用JDBC和本机SQL请求。
    各种“关系映射”技术的优势在于可移植性:您确保应用程序将在大多数ACID数据库上运行。否则,当您手动编写SQL请求时,您将应对不同SQL方言之间的差异。
    当然,您可以限制自己使用SQL92标准(然后进行一些函数式编程),或者您可以重新使用ORM框架的一些概念。
    ORM的优点是建立在会话对象上的,该对象可以作为瓶颈:
    - 它在底层数据库事务正在运行时管理对象的生命周期。 - 它维护Java对象与数据库行之间的一对一映射(并使用内部缓存以避免重复对象)。 - 它自动检测关联更新和要删除的孤立对象。 - 它处理乐观或悲观锁的并发问题。
    然而,它的优点也是它的缺点:
    - 会话必须能够比较对象,因此您需要实现equals / hashCode方法,但对象的相等性必须基于“业务键”,而不是数据库ID(新的瞬态对象没有数据库ID!)。 - 会话必须监视关系更改,但其映射规则推动使用不适合业务算法的集合。有时,您希望使用HashMap,但ORM将要求键是另一个“富域对象”,而不是另一个轻量级对象...然后您必须在扮演键的富域对象上实现对象相等性...但您不能,因为此对象在业务世界中没有对应物。所以你回到一个简单的列表上,你必须迭代它(并且性能问题会导致)。 - ORM API有时不适用于现实世界的使用。例如,真实的Web应用程序通过在获取数据时添加一些“WHERE”子句来强制执行会话隔离...然后“Session.get(id)”不足够,您需要转向更复杂的DSL(HSQL,Criteria API)或返回本机SQL。 - 数据库对象与其他框架专用的其他对象冲突(例如OXM框架=对象/ XML映射)。例如,如果您的REST服务使用Jackson库将业务对象序列化。但这个Jackson恰好映射到Hibernate One。然后,您可以合并两者,并出现API和数据库之间的强耦合,或者您必须实现翻译,ORM节省的所有代码都会在那里丢失...
    另外一方面,FRM是“对象关系映射”(ORM)和本地SQL查询(使用JDBC)之间的权衡。
    解释FRM与ORM之间的差异的最好方法是采用DDD方法。
    • 对象关系映射支持使用"丰富领域对象",这些Java类在数据库事务期间的状态是可变的
    • 函数关系映射依赖于"贫穷领域对象",它们是不可变的(非常之多,你必须每次想要更改其内容时克隆一个新的)
    它释放了对ORM会话的约束,并大多依赖于DSL而非SQL(因此可移植性不重要)。但另一方面,您必须查看事务细节和并发问题。
    List<Person> persons = queryFactory.selectFrom(person)
      .where(
        person.firstName.eq("John"),
        person.lastName.eq("Doe"))
      .fetch();
    

    1

    这也取决于学习曲线。

    Ebean ORM具有相当低的学习曲线(简单的API,简单的查询语言),如果您对JPA注释进行映射(@Entity,@Table,@OneToMany等)感到满意。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接