知識庫 / Spring RSS 訂閱

多表 REST 查詢與 Querydsl Web 支持

REST,Spring
HongKong
5
03:53 AM · Dec 06 ,2025

1. 概述

本教程將繼續講解 Spring Data Querydsl Web Support 的第二部分。在此,我們將重點關注關聯實體以及如何通過 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);
    }
}

我們正在覆蓋<em>customize()</em>方法,以配置默認綁定。在這種情況下,我們將默認方法綁定設置為 equals,應用於所有<em>String</em>屬性。

倉庫設置完成後,我們只需添加一個<em>@RestController</em>來管理 HTTP 查詢。

4. 查詢 Rest 控制器

在第一部分,我們解釋了 Query 中使用 @RestController 接口與 user 存儲庫的關係。在這裏,我們只需重用它。

此外,我們可能需要查詢 address 表,因此,我們將添加類似的方法:

@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 查詢,並連接了 user 實體與新的 address 實體。因此,我們現在可以對 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.