Spring Data(JPA)与JPA持久性提供者之间的关系如何



我正在努力学习JPA,并且已经学到了很多。JPA是一个java规范,提供者实现了这个规范。我理解这一部分。

我不明白的是Spring Data是如何出现的。Spring Data也是像Hibernate或OpenJPA一样的提供者吗?如果不是,那是什么?Spring Data是如何"让事情变得更容易"的?

Spring Data项目通常是一个具有以下任务声明的伞形项目:

…提供了一个熟悉且一致的基于Spring的编程模型,同时保留了特定于商店的特性和功能。

因此,我们通常处理持久性空间,而不仅仅是通过JPA访问关系数据。这里的重要部分有两个方面:

  1. 编程模型而不是通用的API
  2. 支持特定于商店的功能

由于目前数据访问空间如此多样化,尝试使用单个统一的API访问所有商店注定会失败。你最终会得到一个隐藏商店特定部分的最小公分母——有时你会选择性地选择一个特定的商店,因为它的细节。把这些东西抽走完全颠覆了这一点。在我们看来,尤其是尝试使用JPA是错误的,因为它在定义上与关系概念(@Table、联接、事务)有着深刻的联系。

尽管如此,您不想使用完全不同的API,如果您使用多个API或从一个项目切换到另一个项目,也不想丢失存储差异。Spring传统上通过采用一致的编程模型来帮助实现这一点,该模型的特点是抽象以相同的方式工作,但仍然特定于特定的技术。例如,JDBC和JMS是完全不同的技术。Spring提供了JdbcTemplateJmsTemplate,它们涵盖了相同的职责(资源管理和异常转换),并在从使用JDBC转向使用JMS时降低了学习曲线,反之亦然。

Spring Data通过Spring开发人员所知道的抽象来公开特定于商店的功能,从而实现了这一点。我已经提到了模板,但它也包括通用的配置机制(XML名称空间,使用DI和AOP等)

存储库

这个编程模型的最顶层是存储库抽象。在其核心中,它使您避免编写比严格需要的更多的实现代码,从而大大简化了数据访问层的开发。它提供了开箱即用的CRUD功能、分页以及声明性查询方法。

假设一个Customer域类。为它启用持久性只需要声明一个类似于这样的存储库接口:

interface CustomerRepository extends PagingAndSortingRepository<Customer, Long> {
List<Customer> findByLastnameContaining(String lastname);
}

现在,需要配置(和域类映射)才能创建此接口的实例并从客户端使用它。PagingAndSortingRepository包括基本的CRUD功能以及类似Page<Customer> findAll(Pageable pageable)的东西(因此逐页访问)。正如您所看到的,我们还支持查询派生机制,以避免为简单的查询编写任何实现代码。对于更复杂的方法,我们允许手动声明(例如在方法上使用@Query),甚至在必要时允许手动实现。

这里的一个巧妙的副作用是,通过配置中的翻转开关,您可以使用相同的存储库接口将Customer实例持久化到MongoDB中。这并不意味着我们建议盲目地从一个商店转移到另一个商店,因为商店通常需要调整数据模型以有效地工作。然而,它允许开发人员在使用不同存储库的项目之间快速切换,因为存储库的工作方式相同(通过常见的API方法实现编程模型)。

JPA细节

SpringDataJPA实际上是一个实现存储库抽象以及其他一些功能的薄层。因此,我们并没有取代持久性提供者,而是通过API来利用它们,甚至减轻了个别JPA提供者之间的一些怪癖和差异。

将Spring Data视为一种支持JPA和许多其他持久性模型的方式,这种方式对您自己的代码是透明的。Spring Data使您更容易在统一接口中操作更多类型的数据源系统。如果没有SpringData,您将需要在代码中引入更多的适配器,每次都必须处理额外的逻辑。

spring-data JPA不是JPA提供程序。它是一个库/框架,在我们的JPA提供者(Hibernate/TopLink)的顶部添加了一个额外的抽象层。如果您在项目中使用Spring Data,那么您将不会编写大多数低级别的数据访问操作,如编写SQL查询、DAO类等。

但是您必须有一个JPA提供程序(Hibernate、Toplink等)来实现spring数据JPA。

最新更新