JPA与Spring JdbcTemplate比较

108

在处理关系型数据方面,对于一个新项目,JPA是否总是推荐的工具?还是有一些场景下Spring JdbcTemplate更好的选择?以下是您需要考虑的一些因素:

  • 新的数据库架构 vs 既有的架构和表
  • 开发人员的经验水平
  • 与数据缓存层集成的易用性
  • 性能
  • 其他相关因素?

2
你需要考虑的一个额外因素是标准化。 - Eldad Mor
5个回答

170

如果您不想通过领域模型访问数据库架构,则可以使用Spring JdbcTemplate。使用JdbcTemplate,您正在使用更低级别的访问方式,具有更多的灵活性,但可能也需要更多的样板代码。

Spring JdbcTemplate 可以更轻松地处理异构数据库架构和存储过程。使用JPA时,您需要确保数据库架构正确映射到领域模型。

这两种技术都需要开发人员了解关系数据库、SQL和事务。但是使用JPA会有更多的隐藏复杂性。

据我所知,JPA更容易插入数据缓存层,因为面向对象的重点使得缓存条目的识别、更新和失效更容易实现。

您可以更好地调整基于JdbcTemplate的后端,但对于大多数情况来说,涉及的代码更多。

另一个需要考虑的方面是,虽然使用JPA可以获得适用于数据库架构的领域模型,但通常还需要使用其他DTO类。使用JdbcTemplate,您可以直接操作DTO类。


6
对于开发人员需要了解关系型数据库、SQL和事务的观点是很好的,然而JPA允许您将持久层视为由表支持的对象,而不仅仅是表。 - Michael Wiles
@Timo 我试图从连接池的角度理解这个问题。那么,JPA可以像HikarCP这样具有连接池的数据源吗?还是JPA自己处理它? - vijayakumarpsg587

98
我有点晚才看到这篇文章,但我更倾向于使用JdbcTemplate而不是ORM。我很了解SQL,并且真的不想被“抽象”离开我的数据库。我发现大多数时候,我的应用程序都在使用DB视图,我将大部分业务逻辑推到那里。我有正确分层的DAO,其中包括JdbcTemplate实现。感觉很“干净”,大多数样板代码都被JdbcTemplate隐藏了(它的在线文档似乎比ORM的要好得多)。我使用Hibernate等类似工具的时间有限,我发现当它工作时,它可以节省一些时间...但是当它没有正常工作时,它会让我花费数天来进行“WTF”调试。我从未花费超过20分钟来调试JdbcTemplate DAO实现。我认为关键是如其他人所指出的,你对SQL/模式设计的熟悉程度。

2023年的编辑 - 自发布原始答案以来已经过了很长时间。ORM周围的工具已经取得了长足的进步。Spring Data和JPA现在是标准并且具有合理的默认值。我开始欣赏在编写SQL时具有编译安全性。我认为这不是对错问题....它们都是你应该掌握的工具。


57

我同意@Timo的观点。我想补充/扩展的是ORM与纯SQL访问数据的语义不同。

ORM的重点是尽可能地抽象掉你的数据实际上存储在数据库中这个事实。当你正确使用ORM时,所有持久化操作都在一个(希望是薄)层面上处理。您的模型对象将几乎没有持久化代码; 你使用ORM的事实对于你的模型来说应该是看不到的。

因此,ORM非常擅长简单的CRUD操作,能够轻松地加载、呈现、更新和删除模型对象。它会使你的生活变得更容易,因为当你访问数据时,你会得到模型对象,你可以在其上编写业务逻辑。如果你使用JDBC,你需要从数据中“填充”你的对象实例,这可能会很复杂且容易出错。

ORM并不总是最好的选择。JPA是一种工具,如果这个工具不足以胜任工作,你将想要找到更好的工具。例如,我有一个场景,我必须复制整个对象图并保存这些对象的新副本。如果我使用ORM(就像我试图做的那样),我需要将所有对象从数据库中加载出来,然后复制它们,然后保存新的对象。这太费时间了。

更好的解决方案是简单地使用基于JDBC的操作和“通过选择插入”SQL调用来创建新行。它很快,代码更简单。

另一件需要考虑的事情是,如果你熟悉JDBC,并且有期限,你不必跳上ORM的车。Spring JdbcTemplate类非常强大和有用。有时候,最适合工作的工具就是你所知道的。你应该了解ORM,但不一定要在一个期望值很高的项目中使用它。有很多东西需要学习,而且并不容易 - 实际上,你是用JDBC和ORM之间的选择来交换一组复杂性。


11
赞同结束语。通常情况下,这是在JDBC与ORM之间做出的决定,而不是针对JPA与JdbcTemplate的具体选择。 - Parvez
2
内存占用方面怎么样?JdbcTemplate和Spring-Data-Jpa之间有很大的区别吗?(我猜是使用了Hibernate) - razor

46

其他答案中没有提到,但同时使用两者也是可以的。在我的应用程序中,我使用JPA和JdbcTemplate,对于crud类型的操作,我使用JPA,但对于报告或更容易的情况下,我使用JdbcTemplate。

@Repository
public class FooRepository
{
    @PersistenceContext
    private EntityManager entityManager;

    @Autowired(required = true)
    private JdbcTemplate jdbcTemplate;

    public void saveFoo(Foo foo)
    {
         this.entityManager.persist(foo);
    }

    public List<SomeReportPojo> getSomeReport()
    {
         return this.jdbcTemplate.queryForList("SELECT .. ",SomeProjectPojo.class); 
    }
}

Spring 的一大好处是,将 JPA 异常转换为 Spring Dao 异常层次结构的过程同时适用于 JPA 和 jdbcTemplate。因此,在使用 JPA 有意义时,请使用 JPA,在使用 jdbcTemplate 有意义时,请使用 jdbcTemplate。


21
getSomeReport() 方法中,应该使用 this.jdbcTemplate. ... 而不是 this.entityManager. ... 吗? - Jan Zyka
当不使用XML而仅使用注释时,您如何声明JdbcTemplate bean?Spring无法自动完成此操作:我收到NoSuchBeanDefinitionException:找不到类型为[org.springframework.jdbc.core.JdbcTemplate]的合格bean。 - xtian

5

在工作中,我们使用Hibernate JDBCTemplate,因为它具有更大的灵活性。相比JPA,它也具有更好的性能,因为您不会把很多不必要的数据“加载”到您的应用程序中。
在JDBCTemplate中,您的SQL技能可以让您以正确的速度获得所需内容。


5
您好, 请问“hibernate jdbctemplate”是什么意思?是指Hibernate和Spring JDBCTemplate的组合,还是其他什么意思? - qizer

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