对于最新稳定版本,请使用Spring Data Elasticsearch 5.5.5spring-doc.cadn.net.cn

定义仓库接口

要定义仓库接口,首先需要定义一个领域类别特定的仓库接口。 接口必须扩展存储 库并将类型化为域类和ID类型。 如果你想为该领域类型暴露CRUD方法,可以扩展原油仓库,或其变体之一,代替存储 库.spring-doc.cadn.net.cn

微调仓库定义

你可以用几种方式开始使用仓库界面。spring-doc.cadn.net.cn

典型的做法是延长原油仓库,它提供了CRUD功能的方法。 CRUD代表创建(Create)、阅读(Read)、更新(Update)、删除(Delete)。 3.0版本我们也引入了ListCrudRepository这与原油仓库但对于返回多个实体的方法,它返回列表而不是可迭代你可能会觉得这样更容易使用。spring-doc.cadn.net.cn

如果你用的是响应式商店,可能会选择ReactiveCrudRepositoryRxJava3CrudRepository这取决于你使用的响应式框架。spring-doc.cadn.net.cn

如果你用的是Kotlin,可能会选CoroutineCrudRepository该程序利用了 Kotlin 的协程。spring-doc.cadn.net.cn

此外,你还可以延长分页与排序仓库,ReactiveSortingRepository,RxJava3SortingRepositoryCoroutineSortingRepository如果你需要允许指定排序抽象,或者在第一种情况下是a可页面抽象化。 请注意,各排序仓库不再像 Spring Data 版本 3.0 之前那样扩展了各自的 CRUD 仓库。 因此,如果你想同时拥有两个接口的功能,就需要同时扩展两个接口。spring-doc.cadn.net.cn

如果你不想扩展 Spring Data 接口,也可以在仓库接口上标注@RepositoryDefinition. 扩展CRUD仓库接口后,可以暴露出一套作实体的完整方法。 如果你更愿意选择暴露的方法,可以把你想暴露的方法从CRUD仓库复制到你的域仓库。 在此过程中,你可以更改返回方法的类型。 Spring Data 会尽可能保留返回类型。 例如,对于返回多个实体的方法,你可以选择可迭代(Iterable<T>,List<T>,收藏书<T>或者VAVR名单。spring-doc.cadn.net.cn

如果你的应用中有多个仓库都应该有相同的方法集,你可以自定义自己的基础接口来继承。 这样的接口必须注释为@NoRepositoryBean. 这防止了 Spring Data 尝试直接创建该实例而失败,因为它无法确定该仓库的实体,因为它仍然包含一个通用类型的变量。spring-doc.cadn.net.cn

以下示例展示了如何有选择地暴露CRUD方法(findById,在此例中):spring-doc.cadn.net.cn

选择性暴露CRUD方法
@NoRepositoryBean
interface MyBaseRepository<T, ID> extends Repository<T, ID> {

  Optional<T> findById(ID id);

  <S extends T> S save(S entity);
}

interface UserRepository extends MyBaseRepository<User, Long> {
  User findByEmailAddress(EmailAddress emailAddress);
}

在之前的例子中,你为所有域仓库定义了一个通用的基接口,并公开了findById(...)以及保存(...).这些方法会被路由到你选择的Spring Data提供的基础仓库实现中(例如,如果你使用JPA,实现是SimpleJpaRepository),因为它们与 的方法签名匹配原油仓库. 所以用户仓库现在可以保存用户,按ID查找个别用户,并触发查询查找用户通过电子邮件地址。spring-doc.cadn.net.cn

中间仓库接口标注为@NoRepositoryBean. 确保在所有 Spring Data 不该在运行时创建实例的仓库接口中添加该注释。

使用带有多个 Spring 数据模块的仓库

在你的应用中使用独特的 Spring Data 模块会让事情变得简单,因为定义范围内的所有仓库接口都绑定在 Spring Data 模块上。 有时,应用程序需要使用多个 Spring Data 模块。 在这种情况下,仓库定义必须区分持久化技术。 当 Spring Data 检测到类路径上有多个仓库工厂时,会进入严格的仓库配置模式。 严格配置利用仓库或域类的详细信息来决定仓库定义的 Spring Data 模块绑定:spring-doc.cadn.net.cn

  1. 如果仓库定义扩展了模块特定仓库,则该模块是该 Spring Data 模块的有效候选。spring-doc.cadn.net.cn

  2. 如果域类标注了模块特定的类型标注,则它是特定 Spring Data 模块的有效候选。 Spring Data 模块支持第三方注释(例如 JPA 的@Entity)或提供自己的注释(例如:@Document适用于Spring Data、MongoDB和Spring Data Elasticsearch)。spring-doc.cadn.net.cn

以下示例展示了使用模块特定接口(此处为JPA)的仓库:spring-doc.cadn.net.cn

例子1。使用模块特定接口的仓库定义
interface MyRepository extends JpaRepository<User, Long> { }

@NoRepositoryBean
interface MyBaseRepository<T, ID> extends JpaRepository<T, ID> { … }

interface UserRepository extends MyBaseRepository<User, Long> { … }

我的仓库用户仓库扩展JpaRepository在它们的类型层级中。 它们是Spring Data JPA模块的有效候选。spring-doc.cadn.net.cn

以下示例展示了使用通用接口的仓库:spring-doc.cadn.net.cn

例子2。使用通用接口的仓库定义
interface AmbiguousRepository extends Repository<User, Long> { … }

@NoRepositoryBean
interface MyBaseRepository<T, ID> extends CrudRepository<T, ID> { … }

interface AmbiguousUserRepository extends MyBaseRepository<User, Long> { … }

模糊仓库模糊用户仓库仅限延伸存储 库原油仓库在它们的类型层级中。 虽然在使用独特的Spring Data模块时这样做没问题,但多个模块无法区分这些仓库应绑定到哪个特定的Spring Data。spring-doc.cadn.net.cn

以下示例展示了一个使用带注释的域类的仓库:spring-doc.cadn.net.cn

例子3。使用带注释的域类的仓库定义
interface PersonRepository extends Repository<Person, Long> { … }

@Entity
class Person { … }

interface UserRepository extends Repository<User, Long> { … }

@Document
class User { … }

PersonRepository引用,并用JPA注释@Entity注释,因此该仓库显然属于 Spring Data JPA。用户仓库引用用户,并用Spring Data MongoDB的注释@Document注解。spring-doc.cadn.net.cn

以下这个糟糕的例子展示了一个使用带有混合注释的域类的仓库:spring-doc.cadn.net.cn

例子4。使用带有混合注释的域类的仓库定义
interface JpaPersonRepository extends Repository<Person, Long> { … }

interface MongoDBPersonRepository extends Repository<Person, Long> { … }

@Entity
@Document
class Person { … }

这个例子展示了一个域类,同时使用了JPA和Spring Data MongoDB的注释。 它定义了两个仓库,JpaPersonRepositoryMongoDBPersonRepository. 一个用于 JPA,另一个用于 MongoDB。 Spring Data 不再能区分这些仓库,导致行为不明确。spring-doc.cadn.net.cn

存储库类型细节区分域类注释用于严格的存储库配置,以识别特定 Spring Data 模块的存储库候选。 在同一域类型上使用多个持久化技术专用的注释是可能的,并允许在多个持久化技术间重复使用领域类型。 然而,Spring Data 无法再确定唯一模块来绑定仓库。spring-doc.cadn.net.cn

区分仓库的最后一种方法是对仓库基础包进行范围。 基础包定义了扫描仓库接口定义的起点,这意味着仓库定义位于相应的包中。 默认情况下,注释驱动配置使用配置类的包。 基于XML配置的基础包是必备的。spring-doc.cadn.net.cn

以下示例展示了基于注释驱动的基础包配置:spring-doc.cadn.net.cn

基于注释的基础包配置
@EnableJpaRepositories(basePackages = "com.acme.repositories.jpa")
@EnableMongoRepositories(basePackages = "com.acme.repositories.mongo")
class Configuration { … }