Java ORM 技术与 JDBC?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1575762/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 16:24:36  来源:igfitidea点击:

ORM Technologies vs JDBC?

javaormjdbcdatabase-connection

提问by Rachel

My question is regarding ORM and JDBC technologies, on what criteria would you decide to go for an ORM technology as compared to JDBC and other way round ?

我的问题是关于 ORM 和 JDBC 技术,与 JDBC 和其他方式相比,您决定采用 ORM 技术的标准是什么?

Thanks.

谢谢。

采纳答案by OscarRyz

Complexity.

复杂。

ORMIf your application is domain driven and the relationships among objects is complex or you need to have this object defining what the app does.

ORM如果您的应用程序是域驱动的并且对象之间的关系很复杂,或者您需要让这个对象定义应用程序的功能。

JDBC/SQLIf your application is simple enough as to just present data directly from the database or the relationships between them is simple enough.

JDBC/SQL如果您的应用程序足够简单,可以直接从数据库中显示数据,或者它们之间的关系也足够简单。

The book "Patterns of enterprise application architecture" by Martin Fowler explains much better the differences between these two types:

Martin Fowler 所著的“企业应用程序架构模式”一书更好地解释了这两种类型之间的差异:

See: Domain Modeland Transaction Script

请参阅:域模型事务脚本

回答by Rob Bygrave

It also depends on the learning curve.

这也取决于学习曲线。

Ebean ORMhas a pretty low learning curve (simple API, simple query language) if you are happy enough with JPA annotations for mapping (@Entity, @Table, @OneToMany etc).

如果您对用于映射的 JPA 注释(@Entity、@Table、@OneToMany 等)感到满意,Ebean ORM 的学习曲线非常低(简单的 API、简单的查询语言)。

回答by sagar27

JDBC

JDBC

  1. With JDBC, developer has to write code to map an object model's data representation to a relational data model and its corresponding database schema.
  2. With JDBC, the automatic mapping of Java objects with database tables and vice versa conversion is to be taken care of by the developer manually with lines of code.
  3. JDBC supports only native Structured Query Language (SQL). Developer has to find out the efficient way to access database, i.e. to select effective query from a number of queries to perform same task.
  4. Application using JDBC to handle persistent data (database tables) having database specific code in large amount. The code written to map table data to application objects and vice versa is actually to map table fields to object properties. As table changed or database changed then it's essential to change object structure as well as to change code written to map table-to-object/object-to-table.
  5. With JDBC, it is developer's responsibility to handle JDBC result set and convert it to Java objects through code to use this persistent data in application. So with JDBC, mapping between Java objects and database tables is done manually.
  6. With JDBC, caching is maintained by hand-coding.
  7. In JDBC there is no check that always every user has updated data. This check has to be added by the developer.
  1. 使用 JDBC,开发人员必须编写代码来将对象模型的数据表示映射到关系数据模型及其相应的数据库模式。
  2. 使用 JDBC,Java 对象与数据库表的自动映射以及反之亦然的转换将由开发人员通过代码行手动处理。
  3. JDBC 仅支持本机结构化查询语言 (SQL)。开发人员必须找到访问数据库的有效方式,即从多个查询中选择有效的查询来执行相同的任务。
  4. 使用 JDBC 处理具有大量数据库特定代码的持久数据(数据库表)的应用程序。将表数据映射到应用程序对象(反之亦然)的代码实际上是将表字段映射到对象属性。当表更改或数据库更改时,更改对象结构以及更改用于映射表到对象/对象到表的代码是必不可少的。
  5. 对于 JDBC,开发人员有责任处理 JDBC 结果集并通过代码将其转换为 Java 对象,以便在应用程序中使用这些持久数据。因此,对于 JDBC,Java 对象和数据库表之间的映射是手动完成的。
  6. 使用 JDBC,缓存是通过手工编码维护的。
  7. 在 JDBC 中,没有检查每个用户总是更新数据。此检查必须由开发人员添加。


HIBERNATE.

休眠。

  1. Hibernate is flexible and powerful ORM solution to map Java classes to database tables. Hibernate itself takes care of this mapping using XML files so developer does not need to write code for this.
  2. Hibernate provides transparent persistence and developer does not need to write code explicitly to map database tables tuples to application objects during interaction with RDBMS.
  3. Hibernate provides a powerful query language Hibernate Query Language (independent from type of database) that is expressed in a familiar SQL like syntax and includes full support for polymorphic queries. Hibernate also supports native SQL statements. It also selects an effective way to perform a database manipulation task for an application.
  4. Hibernate provides this mapping itself. The actual mapping between tables and application objects is done in XML files. If there is change in Database or in any table then the only need to change XML file properties.
  5. Hibernate reduces lines of code by maintaining object-table mapping itself and returns result to application in form of Java objects. It relieves programmer from manual handling of persistent data, hence reducing the development time and maintenance cost.
  6. Hibernate, with Transparent Persistence, cache is set to application work space. Relational tuples are moved to this cache as a result of query. It improves performance if client application reads same data many times for same write. Automatic Transparent Persistence allows the developer to concentrate more on business logic rather than this application code.
  7. Hibernate enables developer to define version type field to application, due to this defined field Hibernate updates version field of database table every time relational tuple is updated in form of Java class object to that table. So if two users retrieve same tuple and then modify it and one user save this modified tuple to database, version is automatically updated for this tuple by Hibernate. When other user tries to save updated tuple to database then it does not allow saving it because this user does not have updated data.
  1. Hibernate 是一种灵活而强大的 ORM 解决方案,用于将 Java 类映射到数据库表。Hibernate 本身使用 XML 文件处理这种映射,因此开发人员不需要为此编写代码。
  2. Hibernate 提供透明的持久性,开发人员在与 RDBMS 交互期间不需要显式编写代码来将数据库表元组映射到应用程序对象。
  3. Hibernate 提供了一种强大的查询语言 Hibernate Query Language(独立于数据库类型),它以熟悉的类似 SQL 的语法表示,并且完全支持多态查询。Hibernate 还支持本机 SQL 语句。它还为应用程序选择了一种有效的方式来执行数据库操作任务。
  4. Hibernate 本身提供了这种映射。表和应用程序对象之间的实际映射是在 XML 文件中完成的。如果数据库或任何表中有更改,则只需要更改 XML 文件属性。
  5. Hibernate 通过维护对象表映射本身来减少代码行数,并将结果以 Java 对象的形式返回给应用程序。它使程序员免于手动处理持久性数据,从而减少开发时间和维护成本。
  6. Hibernate,具有透明持久性,缓存设置为应用程序工作空间。作为查询的结果,关系元组被移动到这个缓存中。如果客户端应用程序多次读取相同数据以进行相同写入,则会提高性能。Automatic Transparent Persistence 允许开发人员更多地关注业务逻辑而不是这个应用程序代码。
  7. Hibernate 使开发人员能够为应用程序定义版本类型字段,由于这个定义的字段,每次关系元组以 Java 类对象的形式更新到该表时,Hibernate 都会更新数据库表的版本字段。因此,如果两个用户检索相同的元组然后对其进行修改,并且一个用户将此修改后的元组保存到数据库中,则 Hibernate 会自动更新此元组的版本。当其他用户尝试将更新的元组保存到数据库时,它不允许保存它,因为该用户没有更新的数据。

回答by jmlamare

I think you forgot to look at "Functional Relational Mapping"

我想你忘了看“功能关系映射”

I would sum up by saying:

我总结一下:

  • If you want to focus on the data-structures, use an ORM like JPA/Hibernate
  • If you want to shed light on treatments, take a look at FRM libraries: QueryDSL or Jooq
  • If you need to tune your SQL requests to specific databases, use JDBC and native SQL requests
  • 如果您想专注于数据结构,请使用像 JPA/Hibernate 这样的 ORM
  • 如果您想了解治疗方法,请查看 FRM 库:QueryDSL 或 Jooq
  • 如果您需要调整对特定数据库的 SQL 请求,请使用 JDBC 和本机 SQL 请求

The strengh of various "Relational Mapping" technologies is portability: you ensure your application will run on most of the ACID databases. Otherwise, you will cope with differences between various SQL dialects when you write manually the SQL requests.

各种“关系映射”技术的优势在于可移植性:您确保您的应用程序将在大多数 ACID 数据库上运行。否则,您将在手动编写 SQL 请求时应对各种 SQL 方言之间的差异。

Of course you can restrain yourself to the SQL92 standard (and then do some Functional Programming) or you can reuse some concepts of functionnal programming with ORM frameworks

当然你可以约束自己到 SQL92 标准(然后做一些函数式编程)或者你可以使用 ORM 框架重用函数式编程的一些概念

The ORM strenghs are built over a session object which can act as a bottleneck:

ORM 强度是建立在一个会话对象上的,它可以作为一个瓶颈:

  1. it manages the lifecycle of the objects as long as the underlying database transaction is running.
  2. it maintains a one-to-one mapping between your java objects and your database rows (and use an internal cache to avoid duplicate objects).
  3. it automatically detects association updates and the orphan objects to delete
  4. it handles concurrenty issues with optimistic or pessimist lock.
  1. 只要底层数据库事务正在运行,它就会管理对象的生命周期。
  2. 它维护您的 java 对象和您的数据库行之间的一对一映射(并使用内部缓存来避免重复对象)。
  3. 它会自动检测关联更新和要删除的孤立对象
  4. 它处理乐观或悲观锁的并发问题。

Nevertheless, its strengths are also its weaknesses:

尽管如此,它的优点也是它的缺点:

  1. The session must be able to compare objects so you need to implements equals/hashCode methods But Objects equality must be rooted on "Business Keys" and not database id (new transient objects have no database ID!). However, some reified concepts have no business equality (an operation for instance). A common workaround relies on GUIDs which tend to upset database administrators.

  2. The session must spy relationship changes but its mapping rules push the use of collections unsuitable for the business algorithms. Sometime your would like to use an HashMap but the ORM will require the key to be another "Rich Domain Object" instead of another light one... Then you have to implement object equality on the rich domain object acting as a key... But you can't because this object has no counterpart on the business world. So you fall back to a simple list that you have to iterate on (and performance issues result from)

  3. The ORM API are sometimes unsuitable for real-world use. For instance, real world web applications try to enforce session isolation by adding some "WHERE" clauses when you fetch data... Then the "Session.get(id)" doesn't suffice and you need to turn to more complex DSL (HSQL, Criteria API) or go back to native SQL

  4. The database objects conflicts with other objects dedicated to other frameworks (like OXM frameworks = Object/XML Mapping). For instance, if your REST services use Hymanson library to serialize a business object. But this Hymanson exactly maps to an Hibernate One. Then either you merge both and a strong coupling between your API and your database appears Or you must implement a translation and all the code you saved from the ORM is lost there...

  1. 会话必须能够比较对象,因此您需要实现 equals/hashCode 方法但是对象相等必须基于“业务键”而不是数据库 ID(新的瞬态对象没有数据库 ID!)。然而,一些具体化的概念没有业务平等(例如一个操作)。一种常见的解决方法依赖于往往会让数据库管理员感到不安的 GUID。

  2. 会话必须监视关系更改,但其映射规则推动使用不适合业务算法的集合。有时您想使用 HashMap 但 ORM 将要求密钥是另一个“富域对象”而不是另一个轻量级对象……然后您必须在充当密钥的富域对象上实现对象相等性……但是你不能,因为这个对象在商业世界中没有对应物。所以你回到一个简单的列表,你必须迭代(并且导致性能问题)

  3. ORM API 有时不适合实际使用。例如,现实世界的 Web 应用程序尝试通过在获取数据时添加一些“WHERE”子句来强制执行会话隔离......然后“Session.get(id)”是不够的,你需要转向更复杂的 DSL( HSQL、Criteria API) 或返回原生 SQL

  4. 数据库对象与专用于其他框架的其他对象(如 OXM 框架 = 对象/XML 映射)冲突。例如,如果您的 REST 服务使用 Hymanson 库来序列化业务对象。但是这个 Hymanson 正好映射到一个 Hibernate One。然后要么合并两者,然后出现 API 和数据库之间的强耦合,要么必须实现翻译,而从 ORM 中保存的所有代码都将丢失...

On the other side, FRM is a trade-off between "Object Relational Mapping" (ORM) and native SQL queries (with JDBC)

另一方面,FRM 是“对象关系映射”(ORM)和本机 SQL 查询(使用 JDBC)之间的权衡

The best way to explain differences between FRM and ORM consists into adopting a DDD approach.

解释 FRM 和 ORM 之间差异的最佳方法是采用 DDD 方法。

  • Object Relational Mapping empowers the use of "Rich Domain Object" which are Java classes whose states are mutable during the database transaction
  • Functional Relational Mapping relies on "Poor Domain Objects" which are immutable (so much so you have to clone a new one each time you want to alter its content)
  • 对象关系映射允许使用“富域对象”,这些对象是在数据库事务期间状态可变的 Java 类
  • 功能关系映射依赖于不可变的“可怜的域对象”(以至于每次要更改其内容时都必须克隆一个新对象)

It releases the constraints put on the ORM session and relies most of time on a DSL over the SQL (so portability doesn't matter) But on the other hand, you have to look into the transaction details, the concurrency issues

它释放了对 ORM 会话的约束,并且大部分时间依赖于 SQL 上的 DSL(因此可移植性无关紧要)但另一方面,您必须查看事务细节,并发问题

List persons = queryFactory.selectFrom(person) .where( person.firstName.eq("John"), person.lastName.eq("Doe")) .fetch();

列出人员 = queryFactory.selectFrom(person) .where(person.firstName.eq("John"), person.lastName.eq("Doe")) .fetch();