003-spring-data-elasticsearch 3.0.0.0使用【一】-spring-data之概述、核心概念、查询方法、定义Repository接口
零、概述
Spring Data Elasticsearch项目提供了与Elasticsearch搜索引擎的集成。Spring Data Elasticsearch的关键功能区域是一个POJO中心模型,用于与Elastichsearch Documents进行交互并轻松编写存储库样式数据访问层。
0.1、主要功能
1.Spring配置支持使用基于Java的@Configuration类或ES客户端实例的XML名称空间。
2.ElasticsearchTemplate帮助类,提高执行常见ES操作的生产力。包括文档和POJO之间的集成对象映射。
3.功能丰富的对象映射与Spring的转换服务集成
4.自动实现Repository接口,包括支持自定义find[查找器]方法。
5.CDI支持存储库
maven使用上节已说明
0.2、文档说明
参看地址:https://docs.spring.io/spring-data/elasticsearch/docs/3.0.4.RELEASE/reference/html/
0.3、元数据地址
Version Control - https://github.com/spring-projects/spring-data-elasticsearch
Bugtracker - https://jira.spring.io/browse/DATAES
Release repository - https://repo.spring.io/libs-release
Milestone repository - https://repo.spring.io/libs-milestone
Snapshot repository - https://repo.spring.io/libs-snapshot
git:https://github.com/spring-projects/spring-data-elasticsearch
官方发布说明:https://projects.spring.io/spring-data-elasticsearch/
一、Spring Data Repositories
本节信息来自Spring Data Commons模块,支持Java Persistence API (JPA) module
1.1、核心概念
CrudRepository为正在管理的实体类提供了复杂的CRUD功能。
示例一、CrudRepository接口【基本上都是字面含义】
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> { <S extends T> S save(S entity); Optional<T> findById(ID primaryKey); Iterable<T> findAll(); long count(); void delete(T entity); boolean existsById(ID primaryKey); // … more functionality omitted. }
基于CrudRepository接口,也有一些扩展接口JpaRepository
or MongoRepository
. ElasticsearchCrudRepository等。这些接口扩展了CrudRepository接口,并提供了与基础持久化技术的功能以及相当通用的持久化技术无关接口。
示例二、PagingAndSortingRepository
在CrudRepository之上有一个PagingAndSortingRepository抽象,它增加了一些额外的方法来简化对实体的分页访问:
public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> { Iterable<T> findAll(Sort sort); Page<T> findAll(Pageable pageable); }
页面大小为20的用户的第二页
PagingAndSortingRepository<User, Long> repository = // … get access to a bean Page<User> users = repository.findAll(new PageRequest(1, 20));
示例三、派生计数查询
除查询方法外,计数和删除查询的查询派生都可用。
interface UserRepository extends CrudRepository<User, Long> { long countByLastname(String lastname); }
示例四、派生删除查询
interface UserRepository extends CrudRepository<User, Long> { long deleteByLastname(String lastname); List<User> removeByLastname(String lastname); }
1.2、查询方法
标准CRUD功能存储库通常会在底层数据存储上进行查询。使用Spring Data,声明这些查询变成了一个四步过程:
1、声明一个扩展Repository或其子接口的接口,并将其输入到它将处理的域类和ID类型。
interface PersonRepository extends Repository<Person, Long> { … }
2、在接口上声明查询方法。
interface PersonRepository extends Repository<Person, Long> { List<Person> findByLastname(String lastname); }
3、设置Spring为这些接口创建代理实例。通过JavaConfig:
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; @EnableJpaRepositories class Config {}
或者xml配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> <jpa:repositories base-package="com.acme.repositories"/> </beans>
4、获取注入的资源库实例并使用它。
class SomeClient { private final PersonRepository repository; SomeClient(PersonRepository repository) { this.repository = repository; } void doSomething() { List<Person> persons = repository.findByLastname("Matthews"); } }
针对以上四步,以下进行说明
1.3、定义Repository接口
首先定义一个域类特定的存储库接口。该接口必须扩展Repository并键入到域类和ID类型。如果您想为该域类型扩展CRUD方法,请扩展CrudRepository而不是Repository。
1.3.1、定义自定义通用Repository
自定义存储接口将扩展Repository,CrudRepository或PagingAndSortingRepository。或者,如果您不想扩展Spring Data接口,也可以使用@RepositoryDefinition注释您的存储库接口。扩展CrudRepository公开了一套完整的方法来操纵你的实体。如果您想选择暴露的方法,只需将要从CrudRepository公开的内容复制到您的域存储库。
示例、选择性地暴露CRUD方法
@NoRepositoryBean interface MyBaseRepository<T, ID extends Serializable> 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(...)以及save(...)。这些方法将被路由到Spring Data提供的您选择的商店的基础存储库实现中,例如,在JPA SimpleJpaRepository的情况下,因为它们匹配CrudRepository中的方法签名。因此,UserRepository现在可以保存用户,并通过id找到单个用户,并通过他们的电子邮件地址触发查询来查找用户。
请注意,中间存储库接口使用@NoRepositoryBean注释。确保将该注释添加到Spring Data不应在运行时创建实例的所有存储库接口。
1.3.2、空处理存储库方法
从Spring Data 2.0开始,返回单个聚合实例的存储库CRUD方法使用Java 8的Optional来指示潜在的缺失值。除此之外,Spring Data支持在查询方法上返回其他包装类型:
com.google.common.base.Optional
scala.Option
io.vavr.control.Option
javaslang.control.Option (deprecated as Javaslang is deprecated)
或者查询方法可以选择不使用包装类型。详细参看返回值
可空性注释
您可以使用Spring Framework的可空性注释来表示存储库方法的可空约束。他们提供了一个工具友好的方法,并在运行时选择无效检查:
@NonNullApi – 用于包级别来声明参数和返回值的默认行为是不接受或生成空值。
@NonNull – 用于参数或返回值,该参数或返回值不能为空(参数和返回值不需要@NonNullApi)。
@Nullable – 用于可以为空的参数或返回值。
Spring注释使用JSR 305注释进行元注释,JSR 305元注释允许像IDEA,Eclipse或Kotlin这样的工具供应商以通用方式提供空安全支持,而无需为Spring注释提供硬编码支持。为了启用对查询方法的可空约束的运行时检查,您需要使用package-info.java中的Spring的@NonNullApi来激活包级别的非可空性:
示例
@org.springframework.lang.NonNullApi package com.acme;
一旦非空默认就绪,存储库查询方法调用将在运行时验证可空性约束。返回null的时候就会抛出异常,可以使用Nullable注解
//设置了非空 package com.acme; import org.springframework.lang.Nullable; interface UserRepository extends Repository<User, Long> { //如果执行的查询不产生结果,将抛出EmptyResultDataAccessException。在传递给方法的emailAddress为空的情况下会抛出IllegalArgumentException User getByEmailAddress(EmailAddress emailAddress); //如果执行的查询不产生结果,将返回null。也接受null作为emailAddress的值。 @Nullable User findByEmailAddress(@Nullable EmailAddress emailAdress); //如果执行的查询不产生结果,将返回Optional.empty()。在传递给方法的emailAddress为空的情况下会抛出IllegalArgumentException。 Optional<User> findOptionalByEmailAddress(EmailAddress emailAddress); }
1.3.3、将存储库与多个Spring Data模块一起使用
在应用程序中使用唯一的Spring Data模块使事情变得简单,因此定义范围内的所有存储库接口都绑定到Spring Data模块。有时应用程序需要使用多个Spring Data模块。在这种情况下,存储库定义需要区分持久性技术。Spring Data进入严格的资源库配置模式,因为它检测到类路径上的多个资源库工厂。严格配置需要存储库或域类的详细信息来决定存储库定义的Spring Data模块绑定:
1、如果存储库定义扩展了特定于模块的存储库,那么它就是特定的Spring Data模块的有效候选者。
2、如果domain类使用特定于模块的类型注释进行注释,那么它是特定的Spring Data模块的有效候选者。Spring Data模块接受第三方注释(比如JPA的@Entity)或者为Spring Data MongoDB / Spring Data Elasticsearch提供自己的注释,例如@Document。
参看原始文档:地址