Spring Data 4.4-4.5翻译

4.4定义查询方法

仓库代理有两种通过函数名的方式去获得stored-specific的查询方法。它可以通过直接使用定义好的方法名或者通过自己手动定义的方法名来调用查询。可提供的选项依赖于实际场景。然而,以下策略是在使用过程中需要考虑的。

4.4.1查询查找的策略

以下策略是供仓库的架构去解决这种查询。你可以通过在xml文件里配置query-lookup-strategy属性,或者可以在java的配置文件里通过${}赋值给QueryLookupSTrategy属性。实际上这些策略并不支持有些数据存储。

CREATE试图通过方法名称去构建一个stored-specific的查询方法。通用的方式是把大家所熟悉的前缀去掉,解析剩下部分的方法名。更多关于创建查询的内容请查看链接。

USE_DECLARED_QUERY 尝试去查找一个声明的方法,如果木有找到,则会抛出没有找到方法的异常。可以通过在某处定义方法或者声明来使用。可以通过翻阅存储文档去找到合适的存储选项。如果仓库的架构在程序引导时间内没有找到声明的方法,查找失败。

CREATE_IF_NOT_FOUND(默认) 包含了CREATE和USE_DECLARED_QUERY。它会先查找声明的查找,如果没有找到声明的查找,它将会创建一个定制的基于名字的查询方法。这是默认的查找策略并且将会被使用当你没有明确的配置方法的时候。它允许通过名称快速的定义查询,也可以有需要的通过引入声明的查询方法来自定义这些查询

4.4.2创建查询

查询构造器构建Spring Data仓库架构的机制作用于在仓库实体下构建强约束。这种机制会拆解方法里包含的find…BY。。。,然后会解析剩余的部分。引入的选项包含更多的表达式,类似于一个用于在被创建的查询里设置明显的标志的Distinct。然而,第一个出现的By作为一个分隔符去表明真实标准的开始。基础阶段,你可以通过定义实体的条件并使用And和Or把条件联合起来。

Example 11. 从方法名中创建查询

public interface PersonRepository extends Repository<User, Long> {
List<Person> findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
// Enables the distinct flag for the query
 List<Person> findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
 List<Person> findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);
// Enabling ignoring case for an individual property
 List<Person> findByLastnameIgnoreCase(String lastname);
 // Enabling ignoring case for all suitable properties
 List<Person> findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);
// Enabling static ORDER BY for a query
 List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
 List<Person> findByLastnameOrderByFirstnameDesc(String lastname);
}

实际解析方法的结果取决于你创建的查询的持久性的存储。无论如何,以下几点值得注意: 表达式的属性遍历通常是由可以联结的操作符组成的。你可以通过AND和OR来联结属性表达式。你也可以获得类似于Between…等的操作符的支持。支持的操作符因数据库而异,所以请查阅合适的章节。 方法解析器支持为个人特性设置一个IgnoreCase标志(类似于。。。),或者为一种支持忽略特性的类型的所有的属性(通常是String类型,类型于。。。)。忽略特性是否被支持取决于不同的存储。所以请查阅合适的章节。 你可以通过添加一个OrderBy条件到涉及到属性和提供了分类方向(Asc或者Desc)方法查询里。如何创建一个可以支持动态排序的查询方法,请查看。。。

4.4.3属性表达式

属性表达式仅仅只能应用于托管属性上,先前的例子中有说明。你应该在创建查询期间确认你所解析的属性是托管域的类所包含的字段。无论如何,你也能通过串联多个嵌套的属性来定义约束。例如一个Person拥有一个Address,Address也对应着一个ZipCode。在这种情况下一个方法名类似于

List<Person> findByAddressZipCode(ZipCode zipCode); 会创建属性串联x.address.ZipCode。这分解算法通过解析整一部分的(AddressZipCode)作为属性并且用属性名去查找映射类中的属性(以小写模式)。如果匹配将会使用该属性。不然,这个算法会按照驼峰法来分割它,把该属性分割为头部分和尾部分,在我们的例子里会分割成AddressZip和Code属性。若没有匹配的话将会通过建树的方式left(AddressZip,Cod),并继续在其左子树里查询。 尽管大多数情况,这将会得到解决。但这依然有可能会选择错误的属性。假设Person类里面存在addressZip属性。这个算法会首先匹配已经存在的属性,这就导致了查询失败。(因为addressZip属性可能没有Code属性)。 要解决这个问题,建议使用_去手动定义分割点。

List<Person> findByAddress_ZipCode(ZipCode zipCode);

由于我们认为下划线是我们的保留符号。我们强烈建议去跟随java的命名规则(使用驼峰法而不是下划线)。

4.4.4特殊参数处理

你只需要按照上文说的简单的定义你的方法参数,你就能在查询里处理你的参数了。此外,这个架构能够识别特定的类型,像Pageable和Sort,并应用于分页和查询时的动态排序。

Example 12. 在方法里使用分页,切片和排序
Page<User> findByLastname(String lastname, Pageable pageable);
Slice<User> findByLastname(String lastname, Pageable pageable);
List<User> findByLastname(String lastname, Sort sort);
List<User> findByLastname(String lastname, Pageable pageable);

第一个方法允许你把org.springframework.data.domain.Pageable实例传到查询方法里来动态的为你的静态定义的方法增加排序。Page参数知道元素的总数和页数。它是通过架构触发一个计算查询的方法去计算总数目。因为这个将会大大的依赖于存储使用的情况。Slice(切片)可以被用来作为return的代替。当处理一个巨大的结果集的时候,一个Slice只知道是否有下一个可以满足的Slice可用。

排序选项也通过Pageable实例处理。 如果只需要排序,只需向您的方法添加一个org.springframework.data.domain.Sort参数。 你也可以看到,简单地返回一个List也是可能的。 在这种情况下,将不会创建构建实际页面实例所需的附加元数据(这反过来意味着附加计数查询将不会发生),而是简单地在给定的实体范围内限制查询。

要找出所有通过查询得到的页数,你必须触发一个额外的计数方法来实现。默认情况下,这个查询是由你实际触发的方法里派生出来的。

4.4.5限制查询集

查询方法的结果可以通过关键字first或top来限制,它们可以互换使用。 通过把数字追加到top / first,来指定要返回的最大结果。 如果省略该数字,则假定结果大小为1。

Example 13. 使用Top和First来限制查询结果集

User findFirstByOrderByLastnameAsc();
User findTopByOrderByAgeDesc();
Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);
Slice<User> findTop3ByLastname(String lastname, Pageable pageable);
List<User> findFirst10ByLastname(String lastname, Sort sort);
List<User> findTop10ByLastname(String lastname, Pageable pageable);

限制表达式还支持Distinct关键字。此外,对于将结果集限制为一个实例的查询,支持将结果包装为Optional。

如果将分页或切片应用于限制查询分页(以及可用页面的计算),那么它也会会被应用于限制结果集上。

4.4.6流查询集

通过使用Java 8 Stream <T>来递增地处理查询方法的结果作为返回类型。这不是简单地将查询结果包装成流数据的存储,而是使用特定方法来处理流传输。

Example 14. 使用Java 8 Stream<T>的流查询

@Query("select u from User u")
Stream<User> findAllByCustomQueryAndStream();
Stream<User> readAllByFirstnameNotNull();
@Query("select u from User u")
Stream<User> streamAllPaged(Pageable pageable);

流可能会封装基础数据来存储特定资源,因此必须在使用后关闭。您可以使用close()方法或使用Java 7 try-with-resources块手动关闭流。

Example 15. 在try-with-resources块使用Stream<T>作为返回结果

 try (Stream<User> stream = repository.findAllByCustomQueryAndStream()) {
 stream.forEach(…);
 }

不是所有的Spring Data模块支持Stream<T>作为返回结果。

4.4.7异步查询结果

通过使用Spring的异步方法功能可以异步地执行存储库查询。这意味着该方法将在调用时立即返回,并且实际的查询过程将发生在已经提交到Spring任务执行器的任务里。

@Async
 Future<User> findByFirstname(String firstname);
@Async
 CompletableFuture<User> findOneByFirstname(String firstname);
@Async
 ListenableFuture<User> findOneByLastname(String lastname);
  • 使用 java.util.concurrent.Future 作为返回类型。
  • 使用 Java 8 java.util.concurrent.CompletableFuture 作为返回类型。
  • 使用 org.springframework.util.concurrent.ListenableFuture 作为返回类型。

4.5创建存储库实例

在本节中,您为定义的存储库接口创建实例和bean定义。一种方法是使用每个支持存储库机制的Spring Data模块附带的Spring命名空间,尽管我们通常建议使用Java-Config样式配置。

4.5.1XML配置

每个Spring Data模块都包含一个repository元素,它允许您简单地定义一个被Spring扫描的基础包。

Example 16. 通过XML配置Spring Data的仓库

<?xml version="1.0" encoding="UTF-8"?>
 <beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="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">
<repositories base-package="com.acme.repositories" />
</beans:beans>

在前面的例子里,Spring被指定去扫描com.acme.repositories及其所有子包去查找扩展Repository或其子接口之一。对于找到的每个接口,架构通过注册持久性的特定的FactoryBean来创建处理查询方法的调用的适当代理。 每个bean都注册在从接口名称派生的bean名称下,因此UserRepository的接口将注册在userRepository下。 base-package属性允许使用通配符,所以你可以自定义扫描包的模式。

使用过滤器

默认情况下,架构会在配置的基础包下挑选所有继承了持久性的特定的Repository子接口的每个接口,并为其创建一个bean实例。但是,您可能希望更精细的控制哪些接口bean实例获取创建。为此,您需要在<repositories />中使用<include-filter />和<exclude-filter />元素。语义完全等同于Spring的上下文命名空间中的元素。 有关详细信息,请参阅有关这些元素的Spring参考文档。

例如,你可以使用以下的配置从实例里面去排除特定的接口,来构建仓库。

Example 17. 使用过滤器元素
 <repositories base-package="com.acme.repositories">
 <context:exclude-filter type="regex" expression=".*SomeRepository" />
 </repositories>

这个例子过滤了所有被实例化后以SomeRepository结尾的接口。

4.5.2Java配置

还可以通过JavaConfig类上的存储库里特有的@ Enable $ {store} Repositories声明来触发存储库架构。有关Spring容器的基于Java的配置的介绍,请参阅参考文档。
启用Spring Data存储库的示例配置如下所示。

Example 18. 基于仓库配置的声明样例
 @Configuration
 @EnableJpaRepositories("com.acme.repositories")
 class ApplicationConfiguration {
@Bean
 public EntityManagerFactory entityManagerFactory() {
 // …
 }
 }
 该示例使用JPA特定的注释,您可以根据实际使用的存储模块更改它。 这同样适用于EntityManagerFactory bean的定义。 请参阅涵盖商店特定配置的部分。

4.5.3独立使用

您还可以使用Spring容器之外的存储库基础结构,例如 在CDI环境中。 你仍然需要在classpath中有一些Spring类库包,但是通常你也可以用编程方式设置存储库。提供存储库支持的Spring Data模块提供了一个持久性仓库特有的RepositoryFactory的仓库,您可以使用如下。

Example 19. 仓库工厂的独立使用
 RepositoryFactorySupport factory = … // Instantiate factory here
 UserRepository repository = factory.getRepository(UserRepository.class);

转载自 并发编程网 - ifeve.com

时间: 2024-11-01 23:37:47

Spring Data 4.4-4.5翻译的相关文章

《Spring Data官方文档》翻译邀请

转眼间已经11月了,天气也逐渐变得冷了起来,本月并发网组织大家翻译<Spring Data官方指南>,文章比较简单,欢迎使用过或想了解Sring Data的同学参与翻译. 如何领取 通过评论领取想要翻译的文章,每次领取一章或一节(根据内容长短),翻译完后再领取其他章节.领取完成之后,建议在一个星期内翻译完成,如果不能完成翻译,也欢迎你邀请其他同学和你一起完成翻译. 如何提交? 翻译完成之后请登录到并发网提交成待审核状态,会有专门的编辑校对后进行发布.校对完之后被评为A级会升级您为译者,并加入译

springboot(五):spring data jpa的使用

在上篇文章springboot(二):web综合开发中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jpa 常见用法以及注意事项 使用spring data jpa 开发时,发现国内对spring boot jpa全面介绍的文章比较少案例也比较零碎,因此写文章总结一下.本人也正在翻译Spring Data JPA 参考指南,有兴趣的同学欢迎联系我,一起加入翻译中! spring data jpa介绍 首先了解JPA是什么? JPA(Ja

Spring Data 官方文档》Reference Documentation至5.2. Examples Repository

文档结构 参考文档的这一部分讲解Spring Data Cassandra所提供的核心功能. Cassandra 支持 介绍 Cassandra 模块特性设置. Cassandra 资源库 介绍 Cassandra 所支持的资源. 5. Cassandra 支持 Cassandra 包含了非常广泛的特性, 其总结如下 Spring配置支持Cassandra驱动的实例类和副本集使用基于Java的@Configuration类或XML命名空间. CassandraTemplate帮助程序类,可提高执

spring boot(五):spring data jpa的使用

在上篇文章springboot(二):web综合开发中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jpa 常见用法以及注意事项 使用spring data jpa 开发时,发现国内对spring boot jpa全面介绍的文章比较少案例也比较零碎,因此写文章总结一下.本人也正在翻译Spring Data JPA 参考指南,有兴趣的同学欢迎联系我,一起加入翻译中! spring data jpa介绍 首先了解JPA是什么? JPA(Ja

Spring Data Redis 让 NoSQL 快如闪电(2)

[编者按]本文作者为 Xinyu Liu,文章的第一部分重点概述了 Redis 方方面面的特性.在第二部分,将介绍详细的用例.文章系国内 ITOM 管理平台 OneAPM 编译呈现. 把 Redis 当作数据库的用例 现在我们来看看在服务器端 Java 企业版系统中把 Redis 当作数据库的各种用法吧.无论用例的简繁,Redis 都能帮助用户优化性能.处理能力和延迟,让常规 Java 企业版技术栈望而却步. 1. 全局唯一增量计数器 我们先从一个相对简单的用例开始吧:一个增量计数器,可显示某网

Spring Boot 2.x 小新功能 – Spring Data Web configuration

本文提纲 一.前言 二.运行 chapter-5-spring-boot-paging-sorting 工程 三.chapter-5-spring-boot-paging-sorting 工程配置详解 四.小结 运行环境: Mac OS 10.12.x JDK 8 + Spring Boot 2.0.0.M4  一.前言 Spring 2.x 更新了一个小小的功能即: Spring Data Web configuration Spring Boot exposes a new spring.d

Spring Data JPA方法定义规范【从零开始学Spring Boot】

视频&交流平台] à SpringBoot网易云课堂视频 http://study.163.com/course/introduction.htm?courseId=1004329008 à Spring Boot交流平台 http://412887952-qq-com.iteye.com/blog/2321532           事情的起因:有人问过我们这个这个问题:为什么我利用Spring data jpa写的方法没有按照我想要的情况进行执行呢?我记得当时只是告诉他你你先看看Spring

《Spring Data实战》——导读

前言 数据访问领域在过去的7年间发生了重要的变化.过去30年间一直占据企业级数据存储和处理核心位置的关系型数据库已经不能再独领风骚了.在过去的7年间诞生了很多可选的数据存储形式,当然也有的面临着消亡,它们被使用到了带有关键任务的企业级应用程序之中.这些新的数据存储形式是为了解决特定的数据访问问题而设计的,使用关系型数据库通常无法高效地解决这些问题. 将关系型数据库推到拐点的一个问题就是扩展性(scale).试问,我们如何将几百甚至几千TB(terabyte)的数据存储到关系型数据库中?这个问题让

分页-关于 spring data jpa 的 PagingAndSortingRepository

问题描述 关于 spring data jpa 的 PagingAndSortingRepository 比如说@query 我们使用jpql语句 select u from user u where........ 我们使用PagingAndSortingRepository进行分页和排序,可以整整返回json, 但是如果我不要其中的一个属性 我就试着把其他属性都写上去除了不要的那个 例如 select username,passoword from user u where ... 但是问题