在 Spring Data 中以嵌套物件的屬性尋找
1. 概述
在 Spring Data 中,通常使用基於方法名稱的衍生查詢來查詢實體。在處理實體之間的關係(例如巢狀物件)時,Spring Data 提供了各種機制來從這些嵌套物件中擷取資料。
在本教程中,我們將探索如何使用查詢派生和 JPQL(Java 持久性查詢語言)按嵌套物件的屬性進行查詢。
2. 場景概述
讓我們考慮一個包含兩個實體的簡單場景: Customer
和Order
。每個Order
都透過ManyToOne
關係連結到Customer
。
我們想要尋找屬於具有特定email
的客戶的所有訂單。在本例中, email
是Customer
實體的屬性,而我們的主查詢將在Order
實體上執行。
以下是我們的範例實體:
@Entity
@Table(name = "customers")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// getters and setters
}
@Entity
@Table(name = "orders")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Date orderDate;
@ManyToOne
@JoinColumn(name = "customer_id")
private Customer customer;
// getters and setters
}
3.使用查詢派生
Spring Data JPA允許開發人員從儲存庫介面中的方法簽章派生查詢,從而簡化了查詢建立:
3.1.正常用例
在正常情況下,如果我們想要透過關聯的Customer
的email
來尋找Order
實體,我們可以簡單地執行以下操作:
public interface OrderRepository extends JpaRepository<Order, Long> {
List<Order> findByCustomerEmail(String email);
}
產生的 SQL 將如下所示:
select
o.id,
o.customer_id,
o.order_date
from
orders o
left outer join
customers c
on o.customer_id = c.id
where
c.email = ?
3.2.關鍵字大小寫衝突
現在,假設除了嵌套的Customer
物件之外,我們在Order
類別本身中還有一個名為customerEmail
的欄位。在這種情況下,Spring Data JPA 不會像我們期望的那樣僅對customers
表產生查詢:
select
o.id,
o.customer_id,
o.customer_email,
o.order_date
from
orders o
where
o.customer_email = ?
在這種情況下,我們可以使用下劃線字元來定義 JPA 應嘗試拆分關鍵字的位置:
List<Order> findByCustomer_Email(String email);
這裡,底線幫助 Spring Data JPA 正確解析查詢方法。
4. 使用 JPQL 查詢
如果我們想要更好地控制查詢邏輯或執行更複雜的操作,JPQL 是一個不錯的選擇。要使用 JPQL 查詢Order
by Customer
的email
,我們將撰寫以下內容:
@Query("SELECT o FROM Order o WHERE o.customer.email = ?1")
List<Order> findByCustomerEmailAndJPQL(String email);
這使我們能夠靈活地編寫更客製化的查詢,而無需依賴方法名稱約定。
5. 結論
在本文中,我們探討如何透過 Spring Data 中的嵌套物件的屬性來查詢資料。我們介紹了查詢衍生和自訂 JPQL 查詢。透過利用這些技術,我們可以輕鬆處理許多用例。
本教程中的範例程式碼可以在 GitHub 上找到。