問(wèn)題:Hibernate的<many-to-many>雙向關(guān)聯(lián)中,一方加載另一方時(shí),怎么樣達(dá)到按自定義規(guī)則排序的目的呢?
實(shí)例:角色和菜單是多對(duì)多的關(guān)系,為角色分配菜單后,加載菜單時(shí),我需要按照菜單的ID來(lái)排序顯示。
解決辦法:
1. 通過(guò)在hbm配置文件中配置解決,需要自定義比較器。
? 1) 在多對(duì)多的主控端指定sort屬性
? 這里的主控端為role,受控端為menu。
? role的配置為:
?
<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>
menu的配置為:
<set?name="roleMenus"?table="ROLE_MENU">
???<key?column="RM_MENU_MENU_ID"?/>
???<many-to-many?column="RM_ROLE_ROLE_ID"?class="domain.RoleInfoVO"?/>?
??</set>
2) 自定義MenuComparator
?




menu的配置為:




2) 自定義MenuComparator
? 這里需要實(shí)現(xiàn)Comparator接口,自定義比較器

/**?*//**
?*?菜單排序比較器
?*?MenuComparator
?*?@author?allen
?*/

public?class?MenuComparator?implements?Comparator?
{
????

????/**?*//**
?????*?按照菜單的ID進(jìn)行排序?
?????*?@see?java.util.Comparator#compare(java.lang.Object,?java.lang.Object)
?????*/

????public?int?compare(Object?o1,?Object?o2)?
{

????????if(o1?==?null)
{???
????????????return?(o2?==?null)???0?:?1;???
????????}???

????????if(o2?==?null)
{???
????????????return?-1;???
????????}
????????int?cc?=?0;

????????if?(o1?instanceof?MenuInfoVO?&&?o2?instanceof?MenuInfoVO)?
{
????????????
????????????cc?=?(((MenuInfoVO)o1).getId()).compareTo(((MenuInfoVO)o2).getId());
????????}
????????return?((cc?<?0)???-1?:?(cc?>?0)???1?:?0);
????}
}

我在這里是以菜單的ID為排序關(guān)鍵字的,也可通過(guò)其他的諸如時(shí)間等進(jìn)行排序,相當(dāng)靈活,且代碼量不大。







































我在這里是以菜單的ID為排序關(guān)鍵字的,也可通過(guò)其他的諸如時(shí)間等進(jìn)行排序,相當(dāng)靈活,且代碼量不大。
2. 使用idbag為關(guān)系表增加一個(gè)主鍵。
?
<idbag>可以理解為人工的id生成器,就好像是實(shí)體類(lèi)一樣!集合的每一行都有一個(gè)不同的人造關(guān)鍵字。但是,Hibernate沒(méi)有提供任何機(jī)制來(lái)讓你取得某個(gè)特定行的人造關(guān)鍵字。注意
<idbag?name="roleMenus"?table="ROLE_MENU"?order-by="RM_MENU_MENU_ID?desc">??
????<meta?attribute="field-description">菜單列表</meta>??
????????<collection-id?column="id"?type="java.lang.Long">??
??????????<meta?attribute="field-description">主鍵</meta>??
??????????<generator?/>??
????????</collection-id>??
????????<key?column="RM_ROLE_ROLE_ID"/>??
????????<many-to-many?column="RM_MENU_MENU_ID"?class="domain.MenuInfoVO"?/>??
</idbag>?
感覺(jué)第二個(gè)方法是按照我為角色配置菜單的順序排序的,靈活性比較差,所以個(gè)人認(rèn)為還是第一個(gè)方法比較好。
<idbag>
的更新性能要比普通的<bag>
高得多!Hibernate可以有效的定位到不同的行,分別進(jìn)行更新或刪除工作,就如同處理一個(gè)list, map或者set一樣。








感覺(jué)第二個(gè)方法是按照我為角色配置菜單的順序排序的,靈活性比較差,所以個(gè)人認(rèn)為還是第一個(gè)方法比較好。