日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【Hibernate步步为营】--多对多映射详解

發布時間:2025/6/15 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Hibernate步步为营】--多对多映射详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
上篇文章詳細討論了一對多映射,在一對多映射中單向的關聯映射會有很多問題,所以不建議使用如果非要采用一對多的映射的話可以考慮使用雙向關聯來優化之間的關系,一對多的映射其實質上是在一的一端使用<many-to-one>標簽來標明它們之間的關系,另外還需要在一的一端的對象中使用set標明集合映射。


一、單向多對多


? ? ? ? 仍然按照前幾篇的文章格式來討論,首先來看對象之間的關系,單向的多對多關系是兩個對象之間發生的,比如在人和職位之間,一個人可以有多個職位,而且一個職位也可以由多人來負責,所以它們之間就形成了多對多的關系,另外這種單向性是指只能在一端來查詢獲取另一端的內容。另外因為是多對多之間的關系,所以在生成關系模型時會生成對象之間的關聯表,實際它們之間的關系的是關聯表,具體的對象模型如下:


? ? ? ?上面已經說過多對多的關系會生成一個關聯表,在關聯表中來維護之間的關系,所以對應的關系模型中會有一個關系表,這個關系表中存放著兩個關系表的主鍵,并且關系表的主鍵是另外兩張表的主鍵的組合,如下圖:



? ?1.1、映射


? ? ? ? 上面的關系模型中會生成一個關系表,所以在映射中要編寫對應的屬性,因為是單向的關聯關系所以主要的映射關系是在映射的原方向添加的,對應的上面的關系模型上就是在T_user中添加多對多映射的關系。


? ? 1.1.1 User.hbm.xml

? ? ? ? 文件中要使用<many-to-many>標簽,并且在標簽中添加上對應的列關系,因為你要讓兩個對象中都要清楚它們之間的映射是如何使用的,并且在生成的關系表中哪一列是對應的自己的外鍵,所以要在該標簽中指明,另外在<set>標簽中添加table屬性會指明要生成新表,下面的示例中添加了t_user_role,所以會生成新的關聯表。

[html] view plain copy
  • <?xml?version="1.0"?>??
  • <!DOCTYPE?hibernate-mapping?PUBLIC???
  • ????"-//Hibernate/Hibernate?Mapping?DTD?3.0//EN"??
  • ????"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">??
  • <hibernate-mapping>??
  • ????<class?name="com.src.hibernate.User"?table="t_user">??
  • ????????<id?name="id">??
  • ????????????<generator?class="native"/>??
  • ????????</id>??
  • ????????<property?name="name"/>??
  • ????????<set?name="roles"?table="t_user_role">??
  • ????????????<key?column="user_id"></key>??
  • ????????????<many-to-many?class="com.src.hibernate.Role"?column="role_id"></many-to-many>??
  • ????????</set>??
  • ????</class>??
  • </hibernate-mapping>??

  • ? ? 1.1.2 Role.hbm.xml

    ? ? ? ?因為是單向的關系,所以在該映射文件中就不需要添加多余的標簽來維護關系了,它的內部代碼也會很簡單,對應的映射代碼如下:

    [html] view plain copy
  • <?xml?version="1.0"?>??
  • <!DOCTYPE?hibernate-mapping?PUBLIC???
  • ????"-//Hibernate/Hibernate?Mapping?DTD?3.0//EN"??
  • ????"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">??
  • <hibernate-mapping>??
  • ????<class?name="com.src.hibernate.Role"?table="t_role">??
  • ????????<id?name="id">??
  • ????????????<generator?class="native"/>??
  • ????????</id>??
  • ????????<property?name="name"/>??
  • ????</class>??
  • </hibernate-mapping>??


  • ? 1.2、類文件


    ? ? ? 類文件中代碼的編寫要和映射文件中配置的相同,它們之間是相互對應的,在user中因為使用了<set>映射,所以在相應的類文件中也要添加Haseset來標明之間的映射關系。


    ? ? 1.2.1 User.java

    ? ? ?類代碼沒有什么好討論的了,里面的內容和前幾篇文章的大致相同,除了基本的屬性和方法外還需要添加對應的HashSet。


    [java] view plain copy
  • package?com.src.hibernate;??
  • import?java.util.Set;??
  • ??
  • public?class?User?{??
  • ????//ID號??
  • ????private?int?id;??
  • ????public?int?getId()?{??
  • ????????return?id;??
  • ????}??
  • ????public?void?setId(int?id)?{??
  • ????????this.id?=?id;??
  • ????}??
  • ??????
  • ????//名稱??
  • ????private?String?name;??
  • ????public?String?getName()?{??
  • ????????return?name;??
  • ????}??
  • ????public?void?setName(String?name)?{??
  • ????????this.name?=?name;??
  • ????}??
  • ??????
  • ????//角色集合??
  • ????private?Set?roles;??
  • ????public?Set?getRoles()?{??
  • ????????return?roles;??
  • ????}??
  • ????public?void?setRoles(Set?roles)?{??
  • ????????this.roles?=?roles;??
  • ????}??
  • }??

  • ? ? 1.2.2 Role.java

    ? ? ?基本的屬性和方法,它的頁面代碼是非常簡單基礎的,不需要添加任何復雜的內容。
    [java] view plain copy
  • package?com.src.hibernate;??
  • ??
  • public?class?Role?{??
  • ????//id標示??
  • ????private?int?id;??
  • ????public?int?getId()?{??
  • ????????return?id;??
  • ????}??
  • ????public?void?setId(int?id)?{??
  • ????????this.id?=?id;??
  • ????}??
  • ??????
  • ????//名稱??
  • ????private?String?name;??
  • ????public?String?getName()?{??
  • ????????return?name;??
  • ????}??
  • ????public?void?setName(String?name)?{??
  • ????????this.name?=?name;??
  • ????}??
  • ??????
  • }??

  • ? ? ?生成的表結構如下:



    ? 1.3、操作

    ? ? ?1.3.1 插入操作

    ? ? ? 演示插入操作,新創建表后向表中寫入數據,對應著關系模型,在關系模型中最復雜的是關聯表部分,需要添加多個對應角色,并把角色分配到對應的表中,所以首先要創建關系并把關系保存到數據庫中,然后創建用戶Hash表,在Hash表中添加對應的關系,最后創建用戶,然后將Hash表添加到用戶上,代碼如下: [java] view plain copy
  • public?void?testSave(){??
  • ????Session?session=null;??
  • ????try{??
  • ????????//創建session對象??
  • ????????session=HibernateUtils.getSession();??
  • ????????//開啟事務??
  • ????????session.beginTransaction();??
  • ??????????
  • ????????//創建角色1??
  • ????????Role?r1=new?Role();??
  • ????????r1.setName("Doctor");??
  • ????????session.save(r1);??
  • ??????????
  • ????????//創建角色2??
  • ????????Role?r2=new?Role();??
  • ????????r2.setName("Teacher");??
  • ????????session.save(r2);??
  • ??????????
  • ????????//創建角色3??
  • ????????Role?r3=new?Role();??
  • ????????r3.setName("Farmer");??
  • ????????session.save(r3);??
  • ??????????
  • ????????//創建角色4??
  • ????????Role?r4=new?Role();??
  • ????????r4.setName("Woman");??
  • ????????session.save(r4);??
  • ??????????
  • ????????//創建角色5??
  • ????????Role?r5=new?Role();??
  • ????????r5.setName("Father");??
  • ????????session.save(r5);??
  • ??????????
  • ????????//創建用戶1,并設置用戶角色??
  • ????????User?user1=new?User();??
  • ????????user1.setName("Anne");??
  • ????????Set?roles1=new?HashSet();??
  • ????????roles1.add(r1);??
  • ????????roles1.add(r5);??
  • ????????user1.setRoles(roles1);??
  • ????????session.save(user1);??
  • ??????????
  • ????????//創建用戶2,并設置用戶角色??
  • ????????User?user2=new?User();??
  • ????????user2.setName("Jack");??
  • ????????Set?roles2=new?HashSet();??
  • ????????roles2.add(r2);??
  • ????????roles2.add(r4);??
  • ????????user2.setRoles(roles2);??
  • ????????session.save(user2);??
  • ??????????
  • ????????//創建用戶3,并設置用戶角色??
  • ????????User?user3=new?User();??
  • ????????user3.setName("Baby");??
  • ????????Set?roles3=new?HashSet();??
  • ????????roles3.add(r3);??
  • ????????roles3.add(r2);??
  • ????????user3.setRoles(roles3);??
  • ????????session.save(user3);??
  • ??????????
  • ????????session.getTransaction().commit();??
  • ????}catch(Exception?e){??
  • ????????e.printStackTrace();??
  • ????????session.getTransaction().rollback();??
  • ????}finally{??
  • ????????HibernateUtils.closeSession(session);??
  • ????}??
  • }??

  • ? ? ? 執行上面的測試方法,將結構寫入表: 對比上表,一個完整的寫入測試方法編寫完成,將數據寫入到關系中其實相當的簡單,主要是在寫入時弄清楚寫入的先后順序,否則會出現很多null值,另外需要注意的是Hash表部分,首先需要添加對應的Hash表的內容,最后將Hash表寫入到數據庫中。

    ? ? ?1.3.2 讀取操作

    ? ? ? 讀取操作相對于寫入來說就很簡單了,因為是單向的關系,所以在讀取時只能通過一端來讀取另一端的內容,也就是說通過User對象來讀取Role的內容,如下代碼:

    [java] view plain copy
  • public?void?testLoad1(){??
  • ????Session?session=null;??
  • ????try{??
  • ????????session=HibernateUtils.getSession();??
  • ????????session.beginTransaction();??
  • ??????????
  • ????????User?user=(User)session.load(User.class,?1);??
  • ????????Set?users=user.getRoles();??
  • ????????for(Iterator?iter=users.iterator();iter.hasNext();){??
  • ????????????Role?role=(Role)iter.next();??
  • ????????????System.out.println("User.name=?"+user.getName()+"?and?Role.name=?"+role.getName());??
  • ????????}??
  • ??????????
  • ????????session.getTransaction().commit();??
  • ????}catch(Exception?e){??
  • ????????e.printStackTrace();??
  • ????????session.getTransaction().rollback();??
  • ????}finally{??
  • ????????HibernateUtils.closeSession(session);??
  • ????}??
  • }??
  • ? ? ? ? 執行測試方法,打印生成的內容如下: [html] view plain copy
  • Hibernate:?select?user0_.id?as?id0_0_,?user0_.name?as?name0_0_?from?t_user?user0_?where?user0_.id=???
  • Hibernate:?select?roles0_.user_id?as?user1_1_,?roles0_.role_id?as?role2_1_,?role1_.id?as?id2_0_,?role1_.name?as?name2_0_?from?t_user_role?roles0_?left?outer?join?t_role?role1_?on?roles0_.role_id=role1_.id?where?roles0_.user_id=???
  • User.name=?Anne?and?Role.name=?Father??
  • User.name=?Anne?and?Role.name=?Doctor??

  • 二、雙向多對多


    ? ? ? ? 雙向的多對多映射可以看做是單向的一種擴展,它其實是為了設置在兩端同時維護關系,從任何一端都能夠加載到另一端的內容,在實現上和單向的起始端是相同的都要使用<many-to-many>標簽。

    ? ? ? ? 同樣以上面的User和Role來做示例,上面的示例中使用了單向的多對多,不同的是這里要使用雙向關系,所以要在Role的一端添加同樣的映射關系,并在相應的對象中添加集合映射,其中對應的User內的代碼不會發生改變。


    ? ?2.1 Role.hbm.xml

    ? ? ? ?因為是雙向的多對多所以要在對象的兩端同時加入雙向的集合映射,也就是在配置文件中添加<set>標簽,并在標簽中添加<many-to-many>標簽,具體的配置方法類似于上文的User.hbm.xml的配置方法,如下:

    [html] view plain copy
  • <?xml?version="1.0"?>??
  • <!DOCTYPE?hibernate-mapping?PUBLIC???
  • ????"-//Hibernate/Hibernate?Mapping?DTD?3.0//EN"??
  • ????"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">??
  • <hibernate-mapping>??
  • ????<class?name="com.src.hibernate.Role"?table="t_role">??
  • ????????<id?name="id">??
  • ????????????<generator?class="native"/>??
  • ????????</id>??
  • ????????<property?name="name"/>??
  • ??????????
  • ????????<!--?添加集合映射,映射的表名應該同User.hbm.xml中配置的表名相同?-->??
  • ????????<set?name="users"?table="t_user_role">??
  • ????????????<key?column="role_id"/><!--?添加映射的外鍵?-->??
  • ????????????<!--?添加多對多的關系?-->??
  • ????????????<many-to-many?class="com.src.hibernate.User"?column="user_id"></many-to-many>??
  • ????????</set>??
  • ????</class>??
  • </hibernate-mapping>??


  • ??2.2 Role.java

    ? ? 同單向的多對多關系中的文件相同,不過需要在對象中添加集合映射Set,使用set來標明映射的集合,如下代碼:

    [java] view plain copy
  • package?com.src.hibernate;??
  • ??
  • import?java.util.Set;??
  • ??
  • public?class?Role?{??
  • ????//id標示??
  • ????private?int?id;??
  • ????public?int?getId()?{??
  • ????????return?id;??
  • ????}??
  • ????public?void?setId(int?id)?{??
  • ????????this.id?=?id;??
  • ????}??
  • ??????
  • ????//名稱??
  • ????private?String?name;??
  • ????public?String?getName()?{??
  • ????????return?name;??
  • ????}??
  • ????public?void?setName(String?name)?{??
  • ????????this.name?=?name;??
  • ????}??
  • ??????
  • ????//用戶集合??
  • ????private?Set?users;??
  • ????public?Set?getUsers()?{??
  • ????????return?users;??
  • ????}??
  • ????public?void?setUsers(Set?users)?{??
  • ????????this.users?=?users;??
  • ????}??
  • ??????
  • }??

  • ? ? ? ?雙向關聯映射是在單向的關聯映射基礎上配置而來的,只需要在映射文件的兩端同時配置<many-to-many>即可,也就是說User.hbm.xml和User.java代碼和上文中的代碼相同,不發生變化,所以不再重復添加了。

    結語


    ? ? ? ? 完整的單向多對多討論完整,需要注意的主要是user.hbm.xml中配置的方法,需要使用<many-to-many>標簽并且需要生成關系表來維護多對多的關系,其它的內容都是很簡單的。

    總結

    以上是生活随笔為你收集整理的【Hibernate步步为营】--多对多映射详解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。