为什么使用 JPA 而不是使用 JDBC 编写 SQL 查询?

2022-08-31 14:07:56

我一直在阅读几篇文章,什么是支持它以及哪个供应商(DataNucleus,JBoss Hibernate等)JPA (Java Persistent API)

我没有ORM(对象关系映射)的经验。

到目前为止,我所做的是使用DTO和DAO编写自己的数据库类。到目前为止,我对我所拥有的一切感到满意,但想知道为什么人们使用JPA而不是包含SQL的Java文件

对我来说,我觉得写DAO类是可以的,就像下面一样。

public class DAOUsers {
     public void insertNewUser(DTO DtoUser) {
           String query = "INSERT INTO users(username, address) " +
                          "VALUES(DtoUser.username , DtoUser.address)";
           Executor.run(query);
     }

}

我了解到JPA使用JPQL,Java持久查询语言,它对实体对象而不是直接对数据库表进行操作。

我的理解(如果我错了,请纠正我)是这里的实体对象与我的DTO对象相同(有点像bean?

但无论如何..JPA与在我的文件中编写纯SQL相比,有什么真正的好处?似乎使用JPA所需的注释并使SQL不可读对我来说并不真正有吸引力。

如果您需要更多澄清,请告诉我,我是这个话题的新手,想听听一些意见。


答案 1

为什么使用JPA而不是直接在Java File上编写SQL查询(即直接写入JDBC)?

某些项目要求工程师更多地关注对象模型,而不是用于访问数据存储的实际 SQL 查询。这个问题实际上可以解释为

为什么要使用ORM框架?

在不同的上下文中可以有不同的答案。

大多数项目都可以从拥有领域模型中受益,持久性是第二个问题。使用JPA(实现)或大多数其他ORM框架,可以将数据库中的所有实体(即表)建模为Java中的类。此外,还可以将行为嵌入到这些类中,从而实现行为丰富的域模型。此模型中的实体可以具有多种用途,包括替换 DTO 以跨层传输数据的目的。

也就是说,有些地方的ORM框架可能不能直接适应这个问题,特别是当数据模型已经建立时,或者当人们使用遗留系统时,将数据库表映射到Java类是一个不平凡的练习。在某些情况下,如果一个人需要绝对地从ORM框架生成的SQL中调出,那么ORM框架通常是一个不合适的。

相关问题

  1. Java EE Architecture - 在使用像JPA 2这样的ORM时,DAO是否仍然被推荐?
  2. 使用ORM还是普通SQL?
  3. ORM 与手动编码数据访问层

答案 2

虽然这是一个老问题,但我觉得它应该有一个新的答案。我是 JPA 的晚期采用者,我已经断断续续地使用它好几年了,虽然我有一段时间对建立新应用程序的简单性印象深刻,但我对正确完成 JPA 所需的性能、复杂性和学习曲线却无动于衷。这个帖子中的答案实际上加强了我的立场。

首先,@vineet建议“实体可以有多种用途”......我在生产中看到过,我会说这是ORM的鼓励。对于凝聚力和单一责任原则来说,这么多。根据我的经验,向数据库实体添加行为会带来麻烦。我知道这一点,因为我已经做到了,并且活着后悔了。

其次,对于JPA的复杂性,有一些简单的替代方案,它们提供了将类与RDBMS一起使用的能力,而不会出现ORM尝试(不成功)解决的不匹配引起的所有沉重(和性能问题)。十年来,我们一直在一个拥有超过 1,000 个表的应用程序中使用非 JPA 关系类映射工具,我们根本看不出 JPA 比更直接地访问数据库有什么改进。JPA掩盖了数据库的强大功能,同时为类模型增加了开销(以注释和JQL的形式)...它不应该以另一种方式工作吗?

@water暗示了许多在理论上是正确的,但在现实中是不切实际的。例如,在切换了三次后端数据库之后,我可以向读者保证,没有一些配置调整这样的事情,你就完成了。我建议,如果你花很多时间维护你的持久层,你的数据库模型正在发展,你会在JPA中做相同或更多的工作。特别是当JPA中的非平凡查询需要使用JQL时!

几乎每个人都假装JPA开发人员不需要知道SQL。我在实践中看到的是,现在我们必须学习SQLJQL。显然,我们不必做DDL - 但是在任何重要的应用程序中,您当然需要了解DDL。Hibernate甚至不建议使用自动DDL生成。显然,我们不必做DML,除非我们调用本机查询,这当然是不可移植的,会破坏缓存,并且具有与JDBC相同的所有问题...

最终,在结构合理的应用程序中,领域模型独立于业务逻辑,JPA几乎没有为我发现的非常高的学习曲线提供功能 - 因为领域模型实际上非常容易构建。我不会直接使用JDBC,但是像Apache DBUtils这样的东西在JDBC上面提供了一个简单的层,可以将行映射到对象,并且只需一点努力就可以提供JPA的大部分优势,而不会隐藏和开销。

自 JDBC 1.0 以来,我一直在开发 Java 数据库应用程序,使用各种库(以及 JDBC 之前的 iODBC 和 ESQL),仅出于性能原因,我就完成了 JPA。但是,即使性能更好,学习曲线和不完整的抽象也让我严重停顿。JPA很复杂,试图隐藏在我看来,开发人员实际上需要关心的细节。例如,我们最近看到休眠问题 250 删除命令到数据库,当一个就足够了。JPA,就其本质而言,使这种错误变得容易。

我不是在倡导JDBC,我只是在倡导反对JPA。那些不工作或不能在SQL中工作的开发人员可能不应该编写关系应用程序 - 就像我这样不能做矩阵代数来挽救我生命的开发人员一样,应该编写3D游戏。以SQL为生的开发人员应该对休眠状态发送到服务器的扭曲的SQL感到震惊,以避免首先不需要的往返行程。


推荐