Spring Data JPA 參考文件三

Adobe國際認證發表於2021-10-18

原標題:Spring認證|Spring Data JPA 參考文件三(內容來源:Spring中國教育管理中心)

Spring Data JPA 參考文件三

手動接線

如果您的自定義實現僅使用基於註解的配置和自動裝配,則前面顯示的方法效果很好,因為它被視為任何其他 Spring bean。如果您的實現片段 bean 需要特殊連線,您可以根據上一節中描述的約定宣告 bean 併為其命名。然後,基礎設施通過名稱引用手動定義的 bean 定義,而不是自己建立一個。以下示例顯示瞭如何手動連線自定義實現:

示例 38. 自定義實現的手動接線

<repositories base-package="com.acme.repository" />

<beans:bean id="userRepositoryImpl" class="…">

<!-- further configuration -->

</beans:bean>

4.6.2. 自定義基礎儲存庫

當您想要自定義基本儲存庫行為以便影響所有儲存庫時,上一節中描述的方法需要自定義每個儲存庫介面。要改為更改所有儲存庫的行為,您可以建立一個擴充套件永續性技術特定儲存庫基類的實現。然後,此類充當儲存庫代理的自定義基類,如以下示例所示:

示例 39.自定義儲存庫基類

class MyRepositoryImpl<T, ID>

extends SimpleJpaRepository<T, ID> {

private final EntityManager entityManager;

MyRepositoryImpl(JpaEntityInformation entityInformation,

EntityManager entityManager) {

super(entityInformation, entityManager);

// Keep the EntityManager around to used from the newly introduced methods.

this.entityManager = entityManager;

}

@Transactional

public <S extends T> S save(S entity) {

// implementation goes here

}

}

Spring Data JPA 參考文件三

該類需要具有特定於商店的儲存庫工廠實現使用的超類的建構函式。如果儲存庫基類有多個建構函式,則覆蓋一個EntityInformation加上儲存特定基礎結構物件(例如一個EntityManager或模板類)的建構函式。

最後一步是讓 Spring Data 基礎設施知道定製的儲存庫基類。在 Java 配置中,您可以使用註解的repositoryBaseClass屬性來實現@Enable${store}Repositories,如下例所示:

示例 40. 使用 JavaConfig 配置自定義儲存庫基類

@Configuration

@EnableJpaRepositories(repositoryBaseClass = MyRepositoryImpl.class)

class ApplicationConfiguration { … }

XML 名稱空間中提供了相應的屬性,如以下示例所示:

示例 41. 使用 XML 配置自定義儲存庫基類

<repositories base-package="com.acme.repository"

base-class="….MyRepositoryImpl" />

4.7. 從聚合根釋出事件

儲存庫管理的實體是聚合根。在域驅動設計應用程式中,這些聚合根通常釋出域事件。Spring Data 提供了一個名為的註釋@DomainEvents,您可以在聚合根的方法上使用該註釋,以使該釋出儘可能簡單,如以下示例所示:

示例 42. 從聚合根公開域事件

class AnAggregateRoot {

@DomainEvents

Collection<Object> domainEvents() {

// … return events you want to get published here

}

@AfterDomainEventPublication

void callbackMethod() {

// … potentially clean up domain events list

}

}

使用的方法@DomainEvents可以返回單個事件例項或事件集合。它不能接受任何論據。

釋出所有事件後,我們就有了一個用@
AfterDomainEventPublication. 您可以使用它潛在地清理要釋出的事件列表(以及其他用途)。

該方法被稱為一個Spring資料儲存庫的每一次一個save(…),saveAll(…),delete(…)或deleteAll(…)方法被呼叫。

4.8. Spring 資料擴充套件

本節記錄了一組 Spring Data 擴充套件,這些擴充套件支援在各種上下文中使用 Spring Data。目前,大部分整合都針對 Spring MVC。

4.8.1. Querydsl 擴充套件

Querydsl是一個框架,可以通過其流暢的 API 構建靜態型別的 SQL 類查詢。

幾個 Spring Data 模組通過 提供與 Querydsl 的整合QuerydslPredicateExecutor,如以下示例所示:


43.QuerydslPredicateExecutor 介面

public interface QuerydslPredicateExecutor<T> {

Optional<T> findById(Predicate predicate);

Iterable<T> findAll(Predicate predicate);

long count(Predicate predicate);

boolean exists(Predicate predicate);

// … more functionality omitted.

}

查詢並返回與 匹配的單個實體Predicate。

查詢並返回與 匹配的所有實體Predicate。

返回與 匹配的實體數Predicate。

返回匹配的實體是否Predicate存在。

Spring Data JPA 參考文件三

要使用 Querydsl 支援,請擴充套件QuerydslPredicateExecutor您的儲存庫介面,如以下示例所示:

示例 44. 儲存庫上的 Querydsl 整合

interface UserRepository extends CrudRepository<User, Long>, QuerydslPredicateExecutor<User> {

}

前面的示例允許您使用 QuerydslPredicate例項編寫型別安全的查詢,如以下示例所示:

Predicate predicate = user.firstname.equalsIgnoreCase("dave")

.and(user.lastname.startsWithIgnoreCase("mathews"));

userRepository.findAll(predicate);

4.8.2. 網路支援

支援儲存庫程式設計模型的 Spring Data 模組附帶了各種 Web 支援。Web 相關元件要求 Spring MVC JAR 位於類路徑上。其中一些甚至提供與Spring HATEOAS 的整合。通常,通過使用@
EnableSpringDataWebSupportJavaConfig 配置類中的註釋來啟用整合支援,如以下示例所示:

示例 45.啟用 Spring Data Web 支援

@Configuration

@EnableWebMvc

@EnableSpringDataWebSupport

class WebConfiguration {}

該@
EnableSpringDataWebSupport批註註冊幾個元件。我們將在本節後面討論這些。它還檢測類路徑上的 Spring HATEOAS 併為其註冊整合元件(如果存在)。

或者,如果您使用 XML 配置,請註冊
SpringDataWebConfiguration或HateoasAwareSpringDataWebConfiguration作為 Spring bean,如以下示例所示(對於SpringDataWebConfiguration):

示例 46. 在 XML 中啟用 Spring Data Web 支援

<bean class="org.springframework.data.web.config.SpringDataWebConfiguration" />

<!-- If you use Spring HATEOAS, register this one *instead* of the former -->

<bean class="org.springframework.data.web.config.HateoasAwareSpringDataWebConfiguration" />

基本網路支援

上一節中顯示的配置註冊了一些基本元件:

A使用DomainClassConverter類讓 Spring MVC 從請求引數或路徑變數解析儲存庫管理的域類的例項。


HandlerMethodArgumentResolver讓 Spring MVC從請求引數解析Pageable和Sort例項的實現。

Jackson Modules用於反/序列化Point和 等型別Distance,或儲存特定型別,具體取決於所使用的 Spring 資料模組。

使用DomainClassConverter類

本DomainClassConverter類讓你在Spring MVC中的控制器方法簽名使用域型別直接使您不必手動通過資源庫查詢的情況下,如下例所示:

示例 47. 在方法簽名中使用域型別的 Spring MVC 控制器

@Controller

@RequestMapping("/users")

class UserController {

@RequestMapping("/{id}")

String showUserForm(@PathVariable("id") User user, Model model) {

model.addAttribute("user", user);

return "userForm";

}

}

Spring Data JPA 參考文件三

該方法User直接接收例項,不需要進一步查詢。可以通過讓 Spring MVCid先將路徑變數轉換為域類的型別,最終通過呼叫findById(…)為域型別註冊的儲存庫例項來訪問例項來解析例項。

目前,儲存庫必須實現CrudRepository才能被發現進行轉換。

用於可分頁和排序的
HandlerMethodArgumentResolvers

的配置片段中,在示出前一節還註冊一個
PageableHandlerMethodArgumentResolver,以及例項SortHandlerMethodArgumentResolver。註冊啟用Pageable並Sort作為有效的控制器方法引數,如以下示例所示:

示例 48.使用 Pageable 作為控制器方法引數

@Controller

@RequestMapping("/users")

class UserController {

private final UserRepository repository;

UserController(UserRepository repository) {

this.repository = repository;

}

@RequestMapping

String showUsers(Model model, Pageable pageable) {

model.addAttribute("users", repository.findAll(pageable));

return "users";

}

}

Spring Data JPA 參考文件三

前面的方法簽名導致 Spring MVC 嘗試Pageable使用以下預設配置從請求引數派生例項:

Spring Data JPA 參考文件三

要自定義此行為,請分別註冊一個實現
PageableHandlerMethodArgumentResolverCustomizer介面或SortHandlerMethodArgumentResolverCustomizer介面的 bean 。它的customize()方法被呼叫,讓您更改設定,如以下示例所示:

@Bean SortHandlerMethodArgumentResolverCustomizer sortCustomizer() {

return s -> s.setPropertyDelimiter("<-->");

}

如果設定現有的屬性MethodArgumentResolver不足以滿足您的目的,請擴充套件
SpringDataWebConfiguration或啟用 HATEOAS 的等效項,覆蓋pageableResolver()或sortResolver()方法,並匯入您的自定義配置檔案而不是使用@Enable註釋。

如果您需要從請求中解析多個Pageable或多個Sort例項(例如,對於多個表),您可以使用 Spring 的@Qualifier註解來區分一個和另一個。請求引數必須以 為字首${qualifier}_。以下示例顯示了生成的方法簽名:

String showUsers(Model model,

@Qualifier("thing1") Pageable first,

@Qualifier("thing2") Pageable second) { … }

您必須填充thing1_page、thing2_page等。

Pageable傳遞給方法的預設值等效於 a PageRequest.of(0, 20),但您可以通過使用引數@PageableDefault上的註釋來自定義它Pageable。

對可分頁的超媒體支援

Spring HATEOAS 附帶了一個表示模型類 ( PagedResources),它允許Page使用必要的Page後設資料和連結來豐富例項的內容,讓客戶端輕鬆導航頁面。aPage到 a的轉換PagedResources是由 Spring HATEOASResourceAssembler介面的實現完成的,稱為PagedResourcesAssembler. 以下示例顯示瞭如何使用 aPagedResourcesAssembler作為控制器方法引數:

示例 49.使用 PagedResourcesAssembler 作為控制器方法引數

@Controller

class PersonController {

@Autowired PersonRepository repository;

@RequestMapping(value = "/persons", method = RequestMethod.GET)

HttpEntity<PagedResources<Person>> persons(Pageable pageable,

PagedResourcesAssembler assembler) {

Page<Person> persons = repository.findAll(pageable);

return new ResponseEntity<>(assembler.toResources(persons), HttpStatus.OK);

}

}

啟用配置,如前面的示例所示,可以PagedResourcesAssembler將 用作控制器方法引數。呼叫toResources(…)它有以下效果:

的內容Page成為PagedResources例項的內容。

該PagedResources物件PageMetadata附加了一個例項,並填充了來自Page和底層 的資訊PageRequest。

將PagedResources可能會prev和next連線鏈路,根據頁面的狀態。連結指向方法對映到的 URI。新增到該方法的分頁引數與 的設定相匹配,
PageableHandlerMethodArgumentResolver以確保稍後可以解析連結。

假設我們Person在資料庫中有 30 個例項。您現在可以觸發請求 ( ) 並看到類似於以下內容的輸出:GET

{ "links" : [ { "rel" : "next",

"href" : "?page=1&size=20" }

],

"content" : [

… // 20 Person instances rendered here

],

"pageMetadata" : {

"size" : 20,

"totalElements" : 30,

"totalPages" : 2,

"number" : 0

}

}

組裝器生成了正確的 URI 並選擇了預設配置,以將引數解析Pageable為即將到來的請求。這意味著,如果您更改該配置,連結將自動遵守更改。預設情況下,彙編器指向呼叫它的控制器方法,但您可以通過傳遞一個自定義Link來自定義它,該自定義用作構建分頁連結的基礎,這會過載該
PagedResourcesAssembler.toResource(…)方法。

Spring Data Jackson 模組

核心模組和一些特定於商店的模組附帶一組 Jackson 模組,用於 Spring Data 域使用的型別,例如
org.springframework.data.geo.Distance和org.springframework.data.geo.Point。

一旦啟用Web 支援並可用,
com.fasterxml.jackson.databind.ObjectMapper就會匯入這些模組。

在初始化期間SpringDataJacksonModules,像 一樣
SpringDataJacksonConfiguration,被基礎設施接收,以便宣告的com.fasterxml.jackson.databind.Modules 可供 Jackson 使用ObjectMapper。

以下域型別的資料繫結混合由公共基礎結構註冊。

org.springframework.data.geo.Distance

org.springframework.data.geo.Point

org.springframework.data.geo.Box

org.springframework.data.geo.Circle

org.springframework.data.geo.Polygon

單個模組可能會提供額外的SpringDataJacksonModules.

有關更多詳細資訊,請參閱商店特定部分。

網頁資料繫結支援

您可以使用 Spring Data 投影(在Projections 中描述)通過使用JSONPath表示式(需要Jayway JsonPath或XPath表示式(需要XmlBeam)來繫結傳入的請求有效負載,如以下示例所示:

示例 50.使用 JSONPath 或 XPath 表示式的 HTTP 負載繫結

@ProjectedPayload

public interface UserPayload {

@XBRead("//firstname")

@JsonPath("$..firstname")

String getFirstname();

@XBRead("/lastname")

@JsonPath({ "$.lastname", "$.user.lastname" })

String getLastname();

}

可以使用在前面的例子中為一個Spring MVC處理程式方法引數或通過使用所示型別
ParameterizedTypeReference上的方法之一RestTemplate。前面的方法宣告將嘗試查詢firstname給定文件中的任何位置。該lastnameXML查詢是對輸入文件的頂層進行。其 JSON 變體lastname首先嚐試頂級,但如果前者不返回值,也會嘗試lastname巢狀在user子文件中。這樣,無需客戶端呼叫公開的方法(通常是基於類的有效負載繫結的缺點)即可輕鬆減輕源文件結構的更改。

如Projections 中所述,支援巢狀投影。如果該方法返回複雜的非介面型別,ObjectMapper則使用Jackson來對映最終值。

對於 Spring MVC,必要的轉換器一旦@
EnableSpringDataWebSupport處於活動狀態就會自動註冊,並且所需的依賴項在類路徑上可用。對於使用RestTemplate,註冊ProjectingJackson2HttpMessageConverter(JSON)或XmlBeamHttpMessageConverter手動。

有關更多資訊,請參閱規範Spring 資料示例儲存庫中的Web 投影示例。

Querydsl 網路支援

對於那些具有QueryDSL整合的商店,您可以從Request查詢字串中包含的屬性派生查詢。

考慮以下查詢字串:

?firstname=Dave&lastname=Matthews

給定User前面示例中的物件,您可以使用 將查詢字串解析為以下值
QuerydslPredicateArgumentResolver,如下所示:

QUser.user.firstname.eq("Dave").and(QUser.user.lastname.eq("Matthews"))

@
EnableSpringDataWebSupport當在類路徑上找到 Querydsl 時 ,會自動啟用該功能以及。

將 a 新增@QuerydslPredicate到方法簽名提供了一個隨時可用的Predicate,您可以使用
QuerydslPredicateExecutor.

型別資訊通常從方法的返回型別解析。由於該資訊不一定與域型別匹配,因此使用 的root屬性可能是一個好主意QuerydslPredicate。

以下示例顯示瞭如何@QuerydslPredicate在方法簽名中使用:

@Controller

class UserController {

@Autowired UserRepository repository;

@RequestMapping(value = "/", method = RequestMethod.GET)

String index(Model model, @QuerydslPredicate(root = User.class) Predicate predicate,

Pageable pageable, @RequestParam MultiValueMap<String, String> parameters) {

model.addAttribute("users", repository.findAll(predicate, pageable));

return "index";

}

}

將查詢字串引數解析為匹配Predicatefor User。

Spring Data JPA 參考文件三

預設繫結如下:

Object在簡單的屬性上eq。

Object在像屬性一樣的集合上contains。

Collection在簡單的屬性上in。

您可以通過Java 8的bindings屬性@QuerydslPredicate或通過使用 Java 8default methods並將QuerydslBinderCustomizer方法新增到儲存庫介面來自定義這些繫結,如下所示:

interface UserRepository extends CrudRepository<User, String>,

QuerydslPredicateExecutor<User>,

QuerydslBinderCustomizer<QUser> {

@Override

default void customize(QuerydslBindings bindings, QUser user) {

bindings.bind(user.username).first((path, value) -> path.contains(value))

bindings.bind(String.class)

.first((StringPath path, String value) -> path.containsIgnoreCase(value));

bindings.excluding(user.password);

}

}

QuerydslPredicateExecutor提供對特定 finder 方法的訪問Predicate。

QuerydslBinderCustomizer儲存庫介面上定義的自動拾取和快捷方式@QuerydslPredicate(bindings=…)。

將username屬性的繫結定義為簡單contains繫結。

將String屬性的預設繫結定義為不區分大小寫的contains匹配。

password從Predicate解析中排除該屬性。

Spring Data JPA 參考文件三

你可以註冊一個
QuerydslBinderCustomizerDefaults從資源庫或應用特定的繫結之前豆保持預設Querydsl繫結@QuerydslPredicate。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69981720/viewspace-2837927/,如需轉載,請註明出處,否則將追究法律責任。

相關文章