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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

hibernate 多对多(many-to-many)

發布時間:2025/6/15 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hibernate 多对多(many-to-many) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

多對多(many-to-many):在操作和性能方面都不太理想,所以多對多的映射使用較少,實際使用中最好轉換成一對多的對象模型;hibernate會為我們創建中間關聯表,轉換成兩個一對多。

1. E-R圖


?

2. 實體類:

Teacher實體類如下:

Java代碼 ?
  • package?com.reiyen.hibernate.domain;??
  • ??
  • import?java.util.Set;??
  • ??
  • public?class?Teacher?{??
  • ??
  • ????private?int?id;??
  • ????private?String?name;??
  • ????private?Set<Student>?students;??
  • ???????//setter和getter方法??
  • ??
  • }??
  • ?Student實體類如下:

    Java代碼 ?
  • package?com.reiyen.hibernate.domain;??
  • ??
  • import?java.util.Set;??
  • ??
  • public?class?Student?{??
  • ??
  • ????private?int?id;??
  • ????private?String?name;??
  • ????private?Set<Teacher>?teachers;??
  • ????????//setter和getter方法??
  • ??
  • }??
  • ?3.映射文件如下:

    Teacher.hbm.xml如下:

    Xml代碼 ?
  • <?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?package="com.reiyen.hibernate.domain">??
  • ????<class?name="Teacher">??
  • ????????<id?name="id">??
  • ????????????<generator?class="native"?/>??
  • ????????</id>??
  • ????????<property?name="name"?/>??
  • ????????<!--?通過table項告訴hibernate中間表的名稱?-->??
  • ????????<set?name="students"?table="teacher_student">??
  • ????????????<!--?通過key屬性告訴hibernate在中間表里面查詢teacher_id值相應的teacher記錄?-->??
  • ????????????<key?column="teacher_id"?/>??
  • ????????????<!--?通過column項告訴hibernate對student表中查找student_id值相就的studnet記錄?-->??
  • ????????????<many-to-many?class="Student"?column="student_id"?/>??
  • ????????</set>??
  • ????</class>??
  • </hibernate-mapping>??
  • ?Student.hbm.xml如下:

    Xml代碼 ?
  • <?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?package="com.reiyen.hibernate.domain">??
  • ????<class?name="Student"?>??
  • ????????<id?name="id"?>??
  • ????????????<generator?class="native"?/>??
  • ????????</id>??
  • ????????<property?name="name"?/>??
  • ????????<set?name="teachers"?table="teacher_student">??
  • ????????<key?column="student_id"?/>??
  • ????????<many-to-many?class="Teacher"?column="teacher_id"/>??
  • ????????</set>??
  • ????</class>??
  • </hibernate-mapping>??
  • ?一定要注意映射文件中<many-to-many class="Teacher" column="teacher_id"/>中class的值,它必須與你另一個關聯映射文件中的class屬性的name值一致,其實就是與你的實體類的類名一致,如:<many-to-many class="Teacher" column="teacher_id"/>中class的值就不能寫成"teacher"。如果寫成這樣的話,就會拋出如下異常:An association from the table teacher_student refers to an unmapped class: com.reiyen .hibernate.domain.teacher

    4. 測試程序如下:

    Java代碼 ?
  • public?class?Many2Many?{??
  • ????public?static?void?main(String[]?args)?{??
  • ????????add();??
  • ????????//query(1);??
  • ????}??
  • ??
  • ????static?void?query(int?id)?{??
  • ????????Session?s?=?null;??
  • ????????Transaction?tx?=?null;??
  • ????????try?{??
  • ????????????s?=?HibernateUtil.getSession();??
  • ????????????tx?=?s.beginTransaction();??
  • ????????????Teacher?t?=?(Teacher)?s.get(Teacher.class,?id);??
  • ????????????System.out.println("students:"?+?t.getStudents().size());??
  • ????????????tx.commit();??
  • ????????}?finally?{??
  • ????????????if?(s?!=?null)??
  • ????????????????s.close();??
  • ????????}??
  • ????}??
  • ??
  • ????static?void?add()?{??
  • ????????Session?s?=?null;??
  • ????????Transaction?tx?=?null;??
  • ????????try?{??
  • ????????????Set<Teacher>?ts?=?new?HashSet<Teacher>();??
  • ??
  • ????????????Teacher?t1?=?new?Teacher();??
  • ????????????t1.setName("t1?name");??
  • ????????????ts.add(t1);??
  • ??
  • ????????????Teacher?t2?=?new?Teacher();??
  • ????????????t2.setName("t2?name");??
  • ????????????ts.add(t2);??
  • ??
  • ????????????Set<Student>?ss?=?new?HashSet<Student>();??
  • ????????????Student?s1?=?new?Student();??
  • ????????????s1.setName("s1");??
  • ????????????ss.add(s1);??
  • ??
  • ????????????Student?s2?=?new?Student();??
  • ????????????s2.setName("s2");??
  • ????????????ss.add(s2);??
  • ??
  • ????????????t1.setStudents(ss);??//1??
  • ????????????t2.setStudents(ss);??//1??
  • //????????????
  • //??????????s1.setTeachers(ts);??//2??
  • //??????????s2.setTeachers(ts);??//2??
  • ??
  • ????????????s?=?HibernateUtil.getSession();??
  • ????????????tx?=?s.beginTransaction();??
  • ????????????s.save(t1);??
  • ????????????s.save(t2);??
  • ????????????s.save(s1);??
  • ????????????s.save(s2);??
  • ????????????tx.commit();??
  • ????????}?finally?{??
  • ????????????if?(s?!=?null)??
  • ????????????????s.close();??
  • ????????}??
  • ????}??
  • }??
  • ?運行此程序后:控制臺打印的sql語句如下所示:

    Hibernate: insert into Teacher (name) values (?)
    Hibernate: insert into Teacher (name) values (?)
    Hibernate: insert into Student (name) values (?)
    Hibernate: insert into Student (name) values (?)
    Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
    Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
    Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
    Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)

    一共在中間表里面插入了4條記錄。

    中間表結構如下所示:

    DROP TABLE IF EXISTS `test`.`teacher_student`;
    CREATE TABLE? `test`.`teacher_student` (
    ? `teacher_id` int(11) NOT NULL,
    ? `student_id` int(11) NOT NULL,
    ? PRIMARY KEY (`student_id`,`teacher_id`),
    ? KEY `FK2E2EF2DE6C8A2663` (`teacher_id`),
    ? KEY `FK2E2EF2DE5BEEDBC3` (`student_id`),
    ? CONSTRAINT `FK2E2EF2DE5BEEDBC3` FOREIGN KEY (`student_id`) REFERENCES `student` (`id`),
    ? CONSTRAINT `FK2E2EF2DE6C8A2663` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`id`)

    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    表中插入的記錄如下所示:

    mysql> select * from teacher_student;
    +------------+------------+
    | teacher_id | student_id |
    +------------+------------+
    |????????? 1 |????????? 1 |
    |????????? 1 |????????? 2 |
    |????????? 2 |????????? 1 |
    |????????? 2 |????????? 2 |
    +------------+------------+
    4 rows in set (0.00 sec)

    ?

    程序中注釋為1的語句非常重要,它是建立Teacher與Student關聯的語句,如果沒有這兩條語句,雖然程序照樣會執行,但是在中間表teacher_student沒有任何記錄,也就是Teacher與Student之間未關聯。

    當然你也可以通過程序中注釋為2的語句來建立Teacher與Student之間的關聯關系,同樣會產生與注釋為1的語句的效果。但是你不能在程序中同時出現以上四句程序,否則會拋出異常( PRIMARY KEY (`student_id`,`teacher_id`),所以會出現主鍵沖突的異常),:

    Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
    Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
    Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
    Hibernate: insert into teacher_student (teacher_id, student_id) values (?, ?)
    Hibernate: insert into teacher_student (student_id, teacher_id) values (?, ?)
    Hibernate: insert into teacher_student (student_id, teacher_id) values (?, ?)
    Hibernate: insert into teacher_student (student_id, teacher_id) values (?, ?)
    Hibernate: insert into teacher_student (student_id, teacher_id) values (?, ?)
    Exception in thread "main" org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update

    解決上面產生異常的辦法是設置inverse屬性。即在Tearcher一端或Student一端設置inverse="true",即讓他們之中的某一方放棄維護關聯關系。此時,雖然上面四句程序在測試程序中同時出現了(其實就是在對象模型上相互設置了他們的關聯關系),但程序照樣能運行正常,因為了在數據庫模型上,只會有兩句程序生效,也就是沒有設置inverse="true"的那一端會去維護關聯關系。有關inverse的說細信息,可以參看我的文章hibernate級聯(cascade和inverse).

    ?

    執行測試程序中的查詢測試,控制臺打印的信息如下所示:

    Hibernate: select teacher0_.id as id5_0_, teacher0_.name as name5_0_ from Teacher teacher0_ where teacher0_.id=?
    Hibernate: select students0_.teacher_id as teacher1_1_, students0_.student_id as student2_1_, student1_.id as id7_0_, student1_.name as name7_0_ from teacher_student students0_ left outer join Student student1_ on students0_.student_id=student1_.id where students0_.teacher_id=?
    students:2

    從打印出的sql語句可以看出,多對多關系進行查詢時,效率是比較低的。

    總結

    以上是生活随笔為你收集整理的hibernate 多对多(many-to-many)的全部內容,希望文章能夠幫你解決所遇到的問題。

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