原標題:Spring認證|使用 Spring Data Repositories(下)來源:( #spring認證#Spring中國教育管理中心)
對可分頁的超媒體支援
Spring HATEOAS 附帶了一個表示模型類 ( PagedResources),它允許Page使用必要的Page後設資料和連結來豐富例項的內容,讓客戶端輕鬆導航頁面。aPage到 a的轉換PagedResources是由 Spring HATEOASResourceAssembler介面的實現完成的,稱為PagedResourcesAssembler. 以下示例顯示瞭如何使用 aPagedResourcesAssembler作為控制器方法引數:
示例 51.使用 PagedResourcesAssembler 作為控制器方法引數
@Controller
class PersonController {
@Autowired PersonRepository repository;
@RequestMapping(value = "/persons", method = RequestMethod.GET)
HttpEntity persons(Pageable pageable,
PagedResourcesAssembler assembler) {
Page 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.Distanceorg.springframework.data.geo.Pointorg.springframework.data.geo.Boxorg.springframework.data.geo.Circleorg.springframework.data.geo.Polygon
單個模組可能會提供額外的SpringDataJacksonModules.
有關更多詳細資訊,請參閱商店特定部分。
網頁資料繫結支援
您可以使用 Spring Data 投影(在Projections 中描述)透過使用JSONPath表示式(需要Jayway JsonPath或XPath表示式(需要XmlBeam)來繫結傳入的請求有效負載,如以下示例所示:
示例 52.使用 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
@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 parameters) {
model.addAttribute("users", repository.findAll(predicate, pageable));
return "index";
}
}
將查詢字串引數解析為匹配Predicatefor User。
預設繫結如下:
Object在簡單的屬性上eq。
Object在像屬性一樣的集合上contains。
Collection在簡單的屬性上in。
您可以透過Java 8的bindings屬性@QuerydslPredicate或透過使用 Java 8default methods並將QuerydslBinderCustomizer方法新增到儲存庫介面來自定義這些繫結,如下所示:
interface UserRepository extends CrudRepository,
QuerydslPredicateExecutor,
QuerydslBinderCustomizer {
@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解析中排除該屬性。
你可以註冊一個
QuerydslBinderCustomizerDefaults從資源庫或應用特定的繫結之前豆保持預設Querydsl繫結@QuerydslPredicate。
4.8.3. 儲存庫填充器
如果您使用 Spring JDBC 模組,您可能熟悉DataSource使用 SQL 指令碼填充 a 的支援。儲存庫級別上也有類似的抽象,儘管它不使用 SQL 作為資料定義語言,因為它必須與儲存無關。因此,填充器支援 XML(透過 Spring 的 OXM 抽象)和 JSON(透過 Jackson)來定義用於填充儲存庫的資料。
假設您有一個包含data.json以下內容的檔案:
示例 53. JSON 中定義的資料
[ { "_class" : "com.acme.Person",
"firstname" : "Dave",
"lastname" : "Matthews" },
{ "_class" : "com.acme.Person",
"firstname" : "Carter",
"lastname" : "Beauford" } ]
您可以使用 Spring Data Commons 中提供的儲存庫名稱空間的 populator 元素來填充儲存庫。要將前面的資料填充到您的PersonRepository,請宣告一個類似於以下內容的填充器:
示例 54. 宣告一個 Jackson 儲存庫填充器
xmlns:xsi="
xmlns:repository="
xsi:schemaLocation="
前面的宣告導致data.json檔案被 Jackson 讀取和反序列化ObjectMapper。
JSON 物件解組到的型別是透過檢查_classJSON 文件的屬性來確定的。基礎架構最終會選擇合適的儲存庫來處理反序列化的物件。
要改為使用 XML 定義應填充儲存庫的資料,您可以使用該unmarshaller-populator元素。您將其配置為使用 Spring OXM 中可用的 XML marshaller 選項之一。有關詳細資訊,請參閱Spring 參考文件。以下示例顯示瞭如何使用 JAXB 解組儲存庫填充器:
示例 55. 宣告解組儲存庫填充器(使用 JAXB)
xmlns:xsi="
xmlns:repository="
xmlns:oxm="
xsi:schemaLocation="
unmarshaller-ref="unmarshaller" />