場景:Role 與 Menu 多對多,需在載入角色的菜單集合時依菜單 ID 排序。Hibernate 提供兩種機制:
sort 屬性 + 自訂 Comparator(推薦)在關聯維護端(Role)的 <set> 指定 sort="package.MenuComparator":
<set name="roleMenus" table="ROLE_MENU" inverse="false" lazy="false" sort="menu.MenuComparator">
<key column="RM_ROLE_ROLE_ID"/>
<many-to-many column="RM_MENU_MENU_ID" class="domain.MenuInfoVO"/>
</set>
實作 Comparator<MenuInfoVO>:
public class MenuComparator implements Comparator<MenuInfoVO> {
public int compare(MenuInfoVO o1, MenuInfoVO o2) {
if (o1 == null) return o2 == null ? 0 : 1;
if (o2 == null) return -1;
return o1.getId().compareTo(o2.getId()); // 依 ID 排序
}
}
優點:排序規則集中在 Java 類別,彈性高(可依時間、名稱等任意欄位),程式碼量少。
<idbag> + order-by(較不彈性)<idbag name="roleMenus" table="ROLE_MENU" order-by="RM_MENU_MENU_ID desc">
<collection-id column="id" type="java.lang.Long"><generator/></collection-id>
<key column="RM_ROLE_ROLE_ID"/>
<many-to-many column="RM_MENU_MENU_ID" class="domain.MenuInfoVO"/>
</idbag>
依關聯表主鍵順序(即配置順序)排序,若需調整順序必須操作關聯表資料,維護成本高。
優先採用 sort + Comparator,將排序邏輯封裝在領域模型,符合 OO 原則且易於測試與變更。