多表 REST 查詢與 Querydsl Web 支持

REST,Spring
Remote
0
11:10 AM · Dec 01 ,2025

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@RestControlleruser 倉庫上的使用,這裏我們只需重複使用它。

@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)); }

讓我們創建一些測試以查看它是否有效。

5. 集成測試

我們包含了測試,以證明 Querydsl 的工作原理。為此,我們使用 MockMvc 框架來模擬 HTTP 查詢,並與新的實體連接 useraddress。因此,我們現在能夠執行過濾 address 屬性的查詢。

讓我們檢索所有居住在西班牙的用户:

/users?addresses.country=Spain

@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")));
}

結果是,Querydsl 將通過 HTTP 發送的謂詞映射,並生成以下 SQL 腳本:

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. 結論

綜上所述,我們看到 Querydsl 為 Web 客户端提供了一種簡單而強大的替代方案,用於創建動態查詢; 另一個強大的使用該框架的方式。

在第一部分中,我們瞭解到如何從一個表中檢索數據; 因此,現在我們可以添加連接多個表的查詢,為 Web 客户端提供更好的體驗,直接在他們發出的 HTTP 請求中進行過濾。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.