我试图把我的头围绕着JPA,并且学到了很多东西.JPA是一个Java规范,提供程序实现此规范.我明白那一部分.
我不明白的是Spring Data如何进入图片.Spring Data也是像Hibernate或OpenJPA这样的提供商吗?如果没有,那是什么?Spring Data如何"让事情变得更轻松"?
Spring Data项目通常是一个伞形项目,具有以下任务声明:
...提供熟悉且一致的基于Spring的编程模型,同时保留特定于商店的特性和功能.
因此,我们通常不仅通过JPA接近关系数据访问的持久性空间.这里重要的部分是两个部分:
编程模型而不是通用API
支持商店特定功能
由于数据访问空间如此多样化,尝试使用单个统一API来处理所有商店注定要失败.您最终会得到一个隐藏商店特定部分的最小公分母 - 在您选择特定商店的时候,因为它的具体细节.抽象那些完全颠覆了这一点.特别是尝试使用JPA在我们看来是错误的,因为它@Table
根据定义与关系概念(,连接,事务)密切相关.
尽管如此,您仍然不希望使用完全不同的API,如果您使用多个API或从一个项目切换到另一个项目,不要在商店差异中丢失.Spring通过采用一致的编程模型传统上在这方面提供了帮助,该模型具有以相同方式工作但仍特定于特定技术的抽象.例如,JDBC和JMS是完全不同的技术.Spring既提供了一个JdbcTemplate
也提供JmsTemplate
了相同的职责(资源管理和异常转换),并降低了从使用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方法实现编程模型).
Spring Data JPA实际上是一个实现存储库抽象的薄层以及其他一些花哨的东西.因此,我们不会替换持久性提供程序,而是通过API实际利用它们,甚至可以减轻个别JPA提供程序之间的一些怪癖和差异.