關於本書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