关于本书html
介绍
关于这本指南
第一章 前言
第二章 新增及注意点
第三章 项目依赖
第四章 使用Spring Data Repositories
4.1 核心概念
4.2 查询方法
4.3 定义repository的接口
4.4 定义查询方法
4.5. 建立repository实例java
Spring Data JPA 参考指南 中文版
阅读地址: https://www.gitbook.com/book/ityouknow/spring-data-jpa-reference-documentation/details;
Spring Data JPA 参考指南 目前正在翻译当中, 为了方便理解, 咱们也会加入本身的观点和例子, 并不会彻底照搬翻译, 但愿你们理解也欢迎你们一块儿加入和完善.若是发现不通顺或者有歧义的地方, 能够在评论里指出来, 咱们会及时改正的.
Github托管地址: https://github.com/ityouknow/spring-data-jpa-reference-documentation;
原文地址: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/;
咱们会开放权限给每个加入的伙伴 (翻译或者校对),请提早邮箱联系ityouknow@126.com;欢迎你们加入JPA交流群,群号:592638519;欢迎你们加入JPA翻译社QQ群,群号是:567323266;建议使用GitBook Editor(https://www.gitbook.com/editor)编辑。如何参与:任何问题都欢迎直接联系我 ityouknow@126.com。Gitbook 提供了很是棒的在线编辑功能, 因此想贡献的同窗能够直接联系我申请权限!许可证本做品采用 Apache License 2.0 国际许可协议 进行许可. 传播此文档时请注意遵循以上许可协议. 关于本许可证的更多详情可参考:http://www.apache.org/licenses/LICENSE-2.0
贡献者列表git
成员 github |
联系方式 算法 |
Githubspring |
ityouknow mongodb |
ityouknow@126.com 数据库 |
Githubapache |
介绍
很高兴能向你们介绍 spring data jpa, 这是一个数据方便的标准封装, 咱们认为它是java ( JVM ) 世界中构建技术的一个飞跃.spring data jpa 提供了:像操做对象同样操做数据库标准的封装
关于这本指南
这本用户指南还并不完善, 就像 spring data jpa同样还在不断升级中。在这本指南中, spring data jpa的一些功能并无被完整的展现出来. 一些内容的解释也并非十分的清楚, 或者假设关于 spring data jpa你知道得更多. 咱们须要你的帮助来完善这本指南. 在 spring data jpa网站上你能够找到更多关于完善这本指南的信息框架
第一章 前言
1. 项目信息
版本控制 - http://github.com/spring-projects/spring-data-jpa
Bugtracker - https://jira.spring.io/browse/DATAJPA
版本库 - https://repo.spring.io/libs-release
里程碑库 - https://repo.spring.io/libs-milestone
快照存储库 - https://repo.spring.io/libs-snapshot
第二章 新增及注意点
2.1. Spring Data JPA 1.10的新增功能点
1. 支持在查询方法中使用 Projections(映射) ,可获取对象更加细化的信息
2. 支持经过实例来查询
3. 增长如下注解: @EntityGraph , @Lock , @Modifying , @Query ,@QueryHints 和 @Procedure
4. 集合表达式支持Contains关键词
5. AttributeConverters for ZoneId of JSR-310 and ThreeTenBP.
6. 升级到Querydsl 4, Hibernate 5, OpenJPA 2.4 and EclipseLink 2.6.1
2.2. Spring Data JPA 1.11的新增功能点
1. 提升了与Hibernate 5.2的兼容性
2. 支持经过实例来查询的任意匹配模式
3. 优化分页查询
4. 支持在查询推导中使用 exists 映射
第三章 项目依赖
因为spring data依赖于不少不一样的组件,其中大部分都有不一样的版本号,找到兼容的最简单方式就是利用咱们定义的bom模版,在maven项目中,你能够在pom文件中定义这样的片断 <dependencyManagement />例1. 在BOM中使用spring data发布的版本
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-releasetrain</artifactId>
<version>${release-train}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
最新发布的版本是 Kay-SR1 。名字是按照字母顺序的升序来排列,最新可用的列表在这里。版本的命名格式为: ${name}-${release} ,其中 release 是下列5种之一:
1. BUILD-SNAPSHOT - 最新的快照
2. M1, M2 etc. - 里程碑
3. RC1, RC2 etc. - 新版本预发布
4. RELEASE - 正式发布的版本
5. SR1, SR2 etc. - 服务版本
咱们能够在spring data using bom这个连接中查看如何使用BOM模版。此时,你在对JPA的模块引用中不须要添加版本号,以下。
例2.声明一个JPA的模块引用
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependencies>
3.1 使用Spring Boot管理依赖
Spring boot 已经选择了最新的版本,若是你想更新到最新的版本,只需配置 spring-data-releasetrain.version 选择不一样的版原本使用便可。
3.2 Spring 框架
当前的Spring Data模版须要依赖Spring框架5.0.1发布版或者更高,也可使用旧版中修复了bug的版本,可是仍是推荐使用最新的版本。
第四章 使用Spring Data Repositories
Spring Data Repositories的目的是使用不多的代码来实现各类持久层的数据库访问。
Spring数据存储库文件和你的module层
本章解释了Spring的核心概念和接口数据存储库。本章信息来自Spring数据通用模块,它使用配置和代码示例Java Persistence API(JPA)模块。您正在使用的模块等同于调整XML名称空间声明和拓展类型。名称空间引用涵盖了 XML配置(全部使用库API的Spring Data模块都支持) ,库查询关键字涵盖了查询关键词库支持的抽象方法。您可到本指南的相关章节去去查询module层具体特性的详细信息。
4.1核心概念
Spring Data库的核心接口是 Repository 。它使用domain类去管理,domain类中的id类型做为类型参数。这个接口主要做为一个标记接口,依靠具体的类型运做并帮助您发现接口, CrudRepository 提供丰富的CRUD功能去管理实体类。
例 3. CrudRepository 接口
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
<S extends T> S save(S entity); (1)
T findOne(ID primaryKey); (2)
Iterable<T> findAll(); (3)
Long count(); (4)
void delete(T entity); (5)
boolean exists(ID primaryKey); (6)
// … more functionality omitted.
}
(1) 保存指定的实体。
(2) 返回指定id的实体。
(3) 返回全部实体。
(4) 返回实体的数量。
(5) 删除给定的实体。
(6) 代表一个指定id的实体是否存在。
咱们还提供持久性特定于技术的抽象如: JpaRepository 或MongoRepository . 这些接口继承于 CrudRepository ,实现了特定的一些功能。CrudRepository 有一个 PagingAndSortingRepository 抽象,增长了额外的方法来简化对实体的分页访问:
例4: 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));
除了查询方法外,还有统计查询和删除查询。
例5 查询并统计
public interface UserRepository extends CrudRepository<User, Long> {
Long countByLastname(String lastname);
}
例6 查询并删除
public interface UserRepository extends CrudRepository<User, Long> {
Long deleteByLastname(String lastname);
List<User> removeByLastname(String lastname);
}
4.2 查询方法
标准的CRUD功能存储库一般对底层数据存储查询。Spring Data把这些查询变成了四个步骤的过程:
一、声明一个接口扩展库和类型它或者它的一个个子域类和ID类型,它将处理。
interface PersonRepository extends Repository<User, Long> { … }
二、接口上新建条件查询的方法。
interface PersonRepository extends Repository<Person, Long> {
List<Person> findByLastname(String lastname);
}
三、为这些接口建立代理实例,能够经过 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>
在本例中使用的JPA名称空间。若是您正在使用repository中的抽象为任何其余数据源,你须要改变这种适当的名称空间声明你的存储模块来与jpa支持,例如:mongodb。注意,不用经过Java变量来配置包,默认状况下回根据注解的类来自动声明。定制的包扫描可使用 basePackage 属性,特定的库可使用 @Enable 来注解。
四、得到repository 实例注入并使用它。
public class SomeClient {
@Autowired
private PersonRepository repository;
public void doSomething() {
List<Person> persons = repository.findByLastname("Matthews");
}
}
下来的小节详细解释每个步骤。
4.3 定义repository的接口
首先须要定义实体类的接口,接口必须继承repository而且输入实体类型和ID类型,若是须要用到CRUD方法,可使用 CrudRepository 来替代 Repository .
4.3.1 自定义接口
一般,您的存储库接口将会扩展 Repository ,CrudRepository 或 PagingAndSortingRepository。另外,若是你不想继承Spring Data接口,还能够注释库接口 @RepositoryDefinition 。扩展 CrudRepository 公开了一套完整的方法来操做您的实体。 若是你喜欢选择调用方法,简单地复制你想要的曝光 CrudRepository 到你的repository。这容许您定义本身的抽象上的弹性提供数据存储库的功能。
例7.有选择地公开CRUD方法
@NoRepositoryBean
interface MyBaseRepository<T, ID extends Serializable> extends Repository<T, ID> {
T findOne(ID id);
T save(T entity);
}
interface UserRepository extends MyBaseRepository<User, Long> {
User findByEmailAddress(EmailAddress emailAddress);
}
第一步你定义了一个公共基础的接口提供了 findOne(…) 和 save(...) 方法,这些方法将会引入到你选择的spring Data的实现类中,例如JPA: SimpleJpaRepository ,由于他们匹配 CrudRepository 的方法签名,所
以 UserRepository 将会具有 save Users的功能和 findOne(…) 的功能,固然也具有 findByEmailAddress 的功能。
注意,若是中间的repository接口添加了 @NoRepositoryBean 注解,确认你全部的repository都添加了这个注解这时候spring Data 讲会不会建立实例。
4.3.2. 使用Spring Data多模块来建立Repositories
使用惟一的Spring Data模块在应用中是很是简单,但有时候咱们须要多的SpringData模块,好比:须要定义个Repository去区分两种不一样的持久化技术,若是在class path中发现多个Repository时,spring data会进行严格的配置限制,确保每一个repository或者实体决定绑定那个Spring Data模块:
一、若是 repository 定义继承特殊的Repository,他是一个特殊的Spring Data模块
二、若是实体注解了一个特殊的声明,它是一个特殊的spring Data模块,springData模块接收第三方的声明(例如:JPA's @Entity ) 或者提供来自 Spring DataMonggoDB/Spring Data Elasticsearch的 @Document 。
例8. 自定义特殊的Repostity
interface MyRepository extends JpaRepository<User, Long> { }
@NoRepositoryBean
interface MyBaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
…
}
interface UserRepository extends MyBaseRepository<User, Long> {
…
}
MyRepository and UserRepository 继承于 JpaRepository 在这个层级中是对Spring Data JPA 模块的合法替代
例9. 使用通常的接口定义Repository
interface AmbiguousRepository extends Repository<User, Long> {
…
}
@NoRepositoryBean
interface MyBaseRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
…
}
interface AmbiguousUserRepository extends MyBaseRepository<User,Long> {
…
}
AmbiguousRepository 和 AmbiguousUserRepository 仅继承于 Repository 和 CrudRepostory 在他们的层级。当它们使用一个spring data模块的时候是完美的,可是若是使用多模块spring data 是,spirng 没法区分每一个Repository的范围。
例10. 使用实体类注解来定义Repository的使用范围
interface PersonRepository extends Repository<Person, Long> {
…
}
@Entity
public class Person {
…
}
interface UserRepository extends Repository<User, Long> {
…
}
@Document
public class User {
…
}
Person 使用了 @Entity 注解 PersonRepository 引用了它,因此这个仓库清晰的使用了Sping Data JPA。 UserRepository 引用的 User 声明了 @Document 表面这个仓库将使用Spring Data MongoDB 模块。
例11. 使用混合的注解来定义仓库
interface JpaPersonRepository extends Repository<Person, Long> {
…
}
interface MongoDBPersonRepository extends Repository<Person, Long> {
…
}
@Entity
@Document
public class Person {
…
}
这个例子中实体类 Person···使用了两种注解,代表这个实体类既能够用于 JpaPersonRepository 也能够用于 MongoDBPersonRepository ```,SpringData不能肯定仓库类型致使未定义的行为。经过Repository继承或者使用注解都是为了肯定使用那个Spring Data模块。使用多个注解到同一个实体来达到多类型的持久化技术,Spring Data不在限制只能绑定到一个Repostitory中。最后一种方法来区分不一样的仓库类型,使用包路径来判断。不一样的包路径下的仓库使用不一样的仓库类型,经过在配置类 configuration 中声明注解来实现,也能够经过xml配置来定义。
例12: 经过注解来实现不一样包路径,使用不一样的仓库
@EnableJpaRepositories(basePackages = "com.acme.repositories.jpa")
@EnableMongoRepositories(basePackages = "com.acme.repositories.mongo")
interface Configuration { }
4.4 定义查询方法
repository 代理有两种方法去查询。一种是根据方法名或者自定义查询,可用的选项取决于实际的商店。然而,根据相应的策略来决定实际SQL的建立,让咱们看看选择项吧。
4.4.1. 查询查找策略
如下策略可供查询库基础设施来解决。您能够配置策略名称空间经过 querylookup-strategy 属性的XML配置或经过 queryLookupStrategy 启用的属性 ${store} 库注释的Java配置。一些策略可能不支持特定的数据存储。create 试图构建一个能找到查询的查询方法名称。 一般的作法是把给定的一组注明前缀的方法名和解析的方法。USE_DECLARED_QUERY 试图找到一个声明查询并将抛出一个异常状况。查询能够定义注释上。CREATE_IF_NOT_FOUND (默认)结合 CREATE 和 USE_DECLARED_QUERY 。 看起来一个声明查询第一,若是没有声明查询发现,它建立一个定制的基于名称的查询方法。这是默认查找策略,所以若是你不使用任何显式配置。它容许快速查询定义的方法名,还custom-tuning这些查询经过引入须要查询。
2.4.2 建立查询
query builder机制内置为构建约束查询库的实体。带前缀的机制 findXXBy , readAXXBy , queryXXBy , countXXBy , getXXBy 自动解析的其他部分。进一步引入子句能够包含表达式等 Distinct 设置不一样的条件建立查询。然而,第一个 By 做为分隔符来表示实际的标准的开始。 在一个很是基础的查询,能够定义条件 And 或者 Or 。
例 13. 根据方法名建立查询
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 , LessThan (不超过) , GreaterThan , Like 等运算符,这些操做对不一样的数据库可能有所不一样,具体参考各参考文档方法解析支持设置 IgnoreCase 在属性上面(如, findByLastnameIgnoreCase(…) ),或者支持查询全部属性忽略大小写(如, findByLastnameAndFirstnameAllIgnoreCase(…) ), 忽略大小写支持全部的数据库,其它的查询参考相关文档.您能够应用静态排序经过附加一个 OrderBy 基准进行排序,引用属性和方向提供了一个排序( asc 或 Desc )。 建立一个支持动态排序的查询方法,明白了特殊参数处理 。
4.4.3. 属性表达式
属性表达式只能引用的直接财产管理的实体,如前面的示例所示。 在建立查询时你已经确保解析房地产管理的域类的一个属性。 然而,您还能够定义约束经过遍历嵌套属性。 假设一个 Person 有一个 Address 与一个 Zipcode 。 在这种状况下一个方法的名称
List<Person> findByAddressZipCode(ZipCode zipCode);
建立属性遍历 x.address.zipCode 。方法执行首先解释整个部分( AddressZipCode )做为财产和检查的域类属性的名称(小写形式)。 分割源在驼峰式大小写部分从右侧头部和尾巴,试图找到对应的属性,在咱们的例子中,分割为 AddressZip 和 Code 。 分裂不匹配,该算法分割点移动到左( Address ,Zipcode )而后继续,在大多数状况下,这种算法有可能会出现错误,您可使用来解决这种模糊性 _ 在方法名来手动定义遍历点。因此咱们的方法名称最终将像这样:
List<Person> findByAddress_ZipCode(ZipCode zipCode);
若是你的属性名称包含下划线(如。 first_name 中下划线),建议使用驼峰的方式来避免。
4.4.4 特殊参数处理
处理参数查询只需方法参数定义为已经在上面的例子中。除了基础查询将会认识到某些特定类型 Pageable 和 Sort 应用动态查询分页和排序
例 14. 使用 Pageable , Slice 和 Sort 来查询
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实例来动态的添加分页。分页类知道元素的总数和可用页数。它经过基础库来触发一个统计查询计算全部的总数。因为这个查询可能对store消耗巨大,可使用Slice来替代。Slice仅仅知道是否有下一个Slice可用,这对查询大数据已经足够了。排序选项和分页的处理方式同样。若是你须要排序,简单的添加一个org.springframework.data.domain.Sort参数到你的方法便可。也正如你所见,简单的返回一个列表也是能够的,在这种状况下,生产的分页实例所需的附加元数据将不会被建立(这也意味着额外的计数查询可能须要但不必定被公布)。要找到在你的查询中有多少页,你须要触发一个额外的计数查询。按照默认来
说这个查询能够从你实际触发查询中衍生出来
4.4.5. 限制查询结果
查询方法的结果能够经过关键字first或者top来限制,它们能够交替使用。在top/firest后添加数字来表示返回最大的结果数。若是没有数字,则默认假定1做为结果大小。示例15 用 Top 和 First 查询限制结果大小
User findFirstByOrderByLastnameAsc();
User findTopByOrderByAgeDesc();
Page<User> queryFirst10ByLastname(String lastname, Pageablepageable);
Slice<User> findTop3ByLastname(String lastname, Pageable pageable);
List<User> findFirst10ByLastname(String lastname, Sort sort);
List<User> findTop10ByLastname(String lastname, Pageable pageable);
限制表达式也支持Distinct关键字。对于限制查询的结果集定义到一个实例中包装这个结果到一个Optional中也是被支持的。若是分页或者切片被应用到一个限制查询分页(计算多少页可用)则它也能应用于限制结果。要注意结合经过Sort参数动态排序的限制结果允许表达查询的方法为“K”最小的,以及“K”最大的元素。
4.4.6. 流查询结果
查询方法能对以JAVA 8的Stream为返回的结果进行逐步处理。而不是简单地包装查询结果在被用来执行流的流数据存储特定的方法。
例16 以JAVA 8的Stream来进行查询的流处理结果
@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区块手动关闭数据流。
例17 在try-with-resources块中操做一个Stream
try(Stream<User stream = repository.findAllByCustomQueryAndStream()){
stream.forEach(...);
}
当前不是全部的Spring Data模块都支持Stream做为返回类型
4.4.7. 异步查询结果
@Async
Future<User> findByFirstname(String firstname); (1)
@Async
CompletableFuture<User> findOneByFirstname(String firstname); (2)
@Async
ListenableFuture<User> findOneByLastname(String lastname); (3)
(1) 使用 java.util.concurrent.Future 做为返回类型
(2) 使用 Java 8 java.util.concurrent.CompletableFuture 做为返回类型
(3) 使用 org.springframework.util.concurrent.ListenableFuture 做为返回类型
4.5. 建立repository实例
在这个部分你建立实例和为repository接口定义的bean。这样作的一个方法是使用Spring的名称空间,这是与每一个Spring Data模块,支持存储机制,虽然咱们通常建议使用的JAVA配置风格的配置。
4.5.1 XML配置
每个Spring Data模块都包含repositories元素可以让你简单的基于base-package定义来进行Spring扫描。
例18 经过XML来开启Spring Data repositories
<?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>
引用自:https://www.gitbook.com/book/ityouknow/spring-data-jpa-reference-documentation/details