Hibernate 中 <set> 映射的集合預設無序。一對多與多對多關聯常需按特定欄位排序,Hibernate 提供兩種聲明式排序方案:資料庫層面 order-by 與記憶體層面 sort。
適用於 一對多 關聯。在 <set> 元素指定 order-by 屬性,值為 SQL ORDER BY 子句片段。查詢時由資料庫直接返回排序結果,效能最佳。
<set name="clubMessage" table="club_Message" inverse="true" cascade="delete" order-by="create_time desc">
<key column="club_id" />
<one-to-many class="com.test.item.club.domain.ClubMessageVO" />
</set>
含義:一個社區對應多條訊息,按 create_time 降序排列。
適用於 多對多 或需複雜排序邏輯的場景。在 <set> 指定 sort 屬性為實作 java.util.Comparator 的類別全名。資料載入記憶體後由 Hibernate 使用比較器排序。
import java.util.Comparator;
import my.User;
public class GBComparator implements Comparator {
public int compare(Object o1, Object o2) {
if (o1 == null) return o2 == null ? 0 : 1;
if (o2 == null) return -1;
if (o1 instanceof User && o2 instanceof User) {
return ((User) o1).getAccount().compareTo(((User) o2).getAccount());
}
return 0;
}
}
// 映射檔
<set name="users" table="USER_GROUP_REL" cascade="none" inverse="true" sort="my.GBComparator">
<key column="GROUPING_ID" />
<many-to-many column="USER_ID" class="User" />
</set>
含義:使用者集合按帳號排序(中文拼音/字碼順序)。
| 維度 | order-by | sort + Comparator |
|---|---|---|
| 執行層面 | 資料庫(SQL ORDER BY) | JVM 記憶體(Java 比較器) |
| 適用關聯 | 一對多 | 一對多、多對多 |
| 效能 | 優(利用資料庫索引) | 較差(需全量載入記憶體排序) |
| 排序靈活度 | 受限於 SQL 支援 | 極高(可實作任意複雜邏輯) |
| 資料量適合度 | 大量資料 | 小量資料(建議 < 1000 筆) |
order-by,將排序下推到資料庫sortsort 類別必須實作 Comparator 並有無參建構子sort,防止 OOM@OrderBy 註解(JPA)或 Criteria API 動態排序