資料庫視角:Set/Map/Bag 無序,List 有序(按插入順序存儲)。但應用層常需按業務邏輯排序展示,Hibernate 提供兩種排序機制。
適用於 <set>、<map>,在記憶體中對已加載集合排序。
<set name="emails" table="email" sort="natural">
<key column="id"/>
<element type="java.lang.String" column="address"/>
</set>
元素需實作 java.lang.Comparable(String 已實作),按字典序排列。
public class CustomComparator implements Comparator {
public int compare(Object o1, Object o2) {
if (((String)o1).equals(o2)) return 0;
return ((Comparable)o1).compareTo(o2) * -1; // 反序
}
}
<set name="emails" table="email" sort="onlyfun.caterpillar.CustomComparator"> ... </set>
限制:Bag、List 不支援 sort 屬性。
在 SQL 查詢時直接加 ORDER BY,適用於所有集合類型,效能更佳(避免記憶體排序大量數據)。
<set name="emails" table="email" order-by="address desc"> ... </set>
生成 SQL:
select emails0_.id, emails0_.address from email emails0_ where emails0_.id=? order by emails0_.address desc
| 場景 | 推薦方案 | 理由 |
|---|---|---|
| 小數據量、頻繁重新排序、排序邏輯複雜(需 Java 代碼) | JVM 端 | 靈活,不增加 DB 負載 |
| 大數據量、固定排序規則、分頁查詢 | 資料庫端 | 利用索引,避免全量加載進記憶體 |
| List/Bag 類型 | 資料庫端 | 不支援 sort 屬性 |
善用 sort 與 order-by 靈活控制集合呈現順序,根據數據量與業務特性選擇最佳策略,兼顧效能與開發便利性。