1. 概述
在本教程中,我們將繼續學習 Spring Data Querydsl Web 支持 的第二部分。在此,我們將重點關注相關的實體以及如何通過 HTTP 創建查詢。
按照第一部分中使用的相同配置,我們將創建一個基於 Maven 的項目。請參考原始文章以瞭解如何設置基本配置。
2. 實體
首先,我們添加一個新的實體 (地址),建立用户與其地址之間的關係。我們使用了 OneToOne 關係以保持簡單。
因此,我們將擁有以下類:
@Entity
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
@OneToOne(fetch = FetchType.LAZY, mappedBy = "user")
private Address addresses;
// getters & setters
}
@Entity
public class Address {
@Id
@GeneratedValue
private Long id;
private String address;
private String country;
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user;
// getters & setters
}
3. Spring Data 倉庫
到目前為止,我們必須創建 Spring Data 倉庫,就像往常一樣,一個用於每個實體。請注意,這些倉庫將具有 Querydsl 配置。讓我們看看 AddressRepository 倉庫以及框架配置的工作原理:
public interface AddressRepository extends JpaRepository<Address, Long>,
QuerydslPredicateExecutor<Address>, QuerydslBinderCustomizer<QAddress> {
@Override
default void customize(QuerydslBindings bindings, QAddress root) {
bindings.bind(String.class)
.first((SingleValueBinding<StringPath, String>) StringExpression::eq);
}
}
我們正在覆蓋 customize() 方法來配置默認綁定。在這種情況下,我們將默認方法綁定配置為 equals,用於所有 String 屬性。
倉庫設置完成後,我們只需添加一個 @RestController 來管理 HTTP 查詢。
4. 查詢 Rest Controller
在第一部分,我們解釋了 Query@RestController 在 user 倉庫上的使用,這裏我們只需重複使用它。
@GetMapping(value = "/addresses", produces = MediaType.APPLICATION_JSON_VALUE)
public Iterable<Address> queryOverAddress(
@QuerydslPredicate(root = Address.class) Predicate predicate) {
BooleanBuilder builder = new BooleanBuilder();
return addressRepository.findAll(builder.and(predicate));
}
讓我們創建一些測試以查看它是否有效。 我們包含了測試,以證明 Querydsl 的工作原理。為此,我們使用 MockMvc 框架來模擬 HTTP 查詢,並與新的實體連接 user:address。因此,我們現在能夠執行過濾 address 屬性的查詢。 讓我們檢索所有居住在西班牙的用户: /users?addresses.country=Spain 結果是,Querydsl 將通過 HTTP 發送的謂詞映射,並生成以下 SQL 腳本: 綜上所述,我們看到 Querydsl 為 Web 客户端提供了一種簡單而強大的替代方案,用於創建動態查詢; 另一個強大的使用該框架的方式。 在第一部分中,我們瞭解到如何從一個表中檢索數據; 因此,現在我們可以添加連接多個表的查詢,為 Web 客户端提供更好的體驗,直接在他們發出的 HTTP 請求中進行過濾。5. 集成測試
@Test
public void givenRequest_whenQueryUserFilteringByCountrySpain_thenGetJohn() throws Exception {
mockMvc.perform(get("/users?address.country=Spain")).andExpect(status().isOk()).andExpect(content()
.contentType(contentType))
.andExpect(jsonPath("$", hasSize(1)))
.andExpect(jsonPath("$[0].name", is("John")))
.andExpect(jsonPath("$[0].address.address", is("Fake Street 1")))
.andExpect(jsonPath("$[0].address.country", is("Spain")));
}
select user0_.id as id1_1_,
user0_.name as name2_1_
from user user0_
cross join address address1_
where user0_.id=address1_.user_id
and address1_.country='Spain'6. 結論