Hibernate 集合過濾器 是一種特殊的 HQL 查詢,作用於已持久化的集合或陣列。查詢字串可引用 this 代表當前集合元素,本質是在資料庫層面過濾關聯集合,僅加載符合條件的子集,避免全量加載後在記憶體過濾的性能損耗。
場景:Picgroup (相簿) 一對多 Image (圖片)。需求:查詢某相簿下 僅狀態為 'C' (已審核) 的圖片。
String hql = "select p from Picgroup p join p.images t where p.id=" + groupId; Query query = session.createQuery(hql); List list = query.list(); Picgroup group = (Picgroup) list.get(0); // group.getImages() 此時包含所有狀態圖片,需記憶體過濾
// 1. 先載入主實體(可用 get/load)
Picgroup group = (Picgroup) session.get(Picgroup.class, groupId);
// 2. 對持久化集合應用過濾器,僅查詢 state='C' 的子集
Collection filteredImages = session.filter(group.getImages(), "select this where this.state='C'");
Iterator it = filteredImages.iterator();
while (it.hasNext()) {
Image img = (Image) it.next();
// 處理已審核圖片...
}
session.filter(collection, queryString):第一參數為已持久化的集合引用(必須是關聯關係的集合屬性),第二參數為 HQL 片段,this 代表集合元素別名。WHERE 子句直接在資料庫過濾,網路傳輸與記憶體佔用均降低。setFirstResult/MaxResults),複雜條件建議改用獨立 HQL/Criteria 查詢 DTO。| 方式 | 適用場景 | 靈活度 | 性能 |
|---|---|---|---|
session.filter() | 動態條件過濾已加載實體的集合 | 高(運行時決定條件) | 好(資料庫過濾) |
| 獨立 HQL/Criteria | 複雜查詢、需分頁、投影 DTO | 最高 | 最佳 |
@Where(clause="state='C'") (映射註解) | 固定業務規則(如軟刪除過濾) | 低(靜態) | 好 |
filter() 是輕量級選擇。deleted=false)直接在映射層用 @Where 或 <loader query-ref="..."/> 宣告。掌握 session.filter(),能在「不破壞實體圖完整性」與「避免全量加載」之間找到平衡點。