Spring Data JPA(官方文檔翻譯)


關於本書

介紹
關於這本指南
第一章 前言
第二章 新增及注意點
第三章 項目依賴
第四章 使用Spring Data Repositories
4.1 核心概念
4.2 查詢方法
4.3 定義repository的接口
4.4 定義查詢方法
4.5. 創建repository實例

 

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
貢獻者列表

成員

聯系方式

Github

ityouknow

ityouknow@126.com

Github


介紹
很高興能向大家介紹 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把這些查詢變成了四個步驟的過程:
1、聲明一個接口擴展庫和類型它或者它的一個個子域類和ID類型,它將處理。
   interface PersonRepository extends Repository<User, Long> { … }
2、接口上新建條件查詢的方法。
   interface PersonRepository extends Repository<Person, Long> {
      List<Person> findByLastname(String lastname);
   }
3、為這些接口創建代理實例,可以通過 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 來注解。
4、獲得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模塊:
  1、如果 repository 定義繼承特殊的Repository,他是一個特殊的Spring Data模塊
  2、如果實體注解了一個特殊的聲明,它是一個特殊的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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM