




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、hibernate中雙向關(guān)聯(lián)在級(jí)聯(lián)情況下save對(duì)象討論一般在雙向關(guān)聯(lián)的情況下,都要在一方設(shè)置mappedBy(name="xxx"),由對(duì)方主導(dǎo)映射關(guān)系。在多對(duì)一的情況下,一般在多的一方設(shè)置主導(dǎo)映射的關(guān)系(為了方便敘述,就這么叫它了,呵呵)。所謂主導(dǎo)這種映射關(guān)系,如group,user,就是由多的一方(user)里面產(chǎn)生一個(gè)外鍵參考一的一方(group)的主鍵,這時(shí)候user就是主導(dǎo)的一方,寫mappedBy是被主導(dǎo)的一方。在多對(duì)多的情況下,隨便由那方主導(dǎo),在數(shù)據(jù)庫表的結(jié)構(gòu)上都是一樣的,都會(huì)產(chǎn)生一個(gè)中間表,中間表有兩個(gè)字段的聯(lián)合主鍵,分別作為外鍵參考兩個(gè)多的一方。在一對(duì)多
2、和多對(duì)多的雙向關(guān)聯(lián)的情況下,并且在cascade=CascadeType.ALL情況下,save不同方面(如主導(dǎo)關(guān)系一方或被主導(dǎo)的一方)在級(jí)聯(lián)的具體表現(xiàn)上是不同的。分別來討論一下。先看一對(duì)多的雙向關(guān)聯(lián)關(guān)系,這里就拿group和user舉例。Group類如下:java view plain copy1. package com.chen.hibernate.ormapping; 2. 3. import java.util.HashSet; 4. import java.util
3、.Set; 5. 6. import javax.persistence.CascadeType; 7. import javax.persistence.Entity; 8. import javax.persistence.FetchType; 9. import javax.persistence.GeneratedValue; 10. import javax.persistence.Id; &
4、#160;11. import javax.persistence.OneToMany; 12. import javax.persistence.Table; 13. 14. Entity 15. Table(name = "t_group") 16. public class Group 17. private
5、;int id; 18. private String name; 19. private Set<User> users = new HashSet<User>(); 20. 21. Id 22.
6、160;GeneratedValue 23. public int getId() 24. return id; 25. 26. 27. public void setId(int
7、160;id) 28. this.id = id; 29. 30. 31. public String getName() 32. r
8、eturn name; 33. 34. 35. public void setName(String name) 36. = name; 37.
9、0; 38. 39. / 設(shè)置mappedBy是被主導(dǎo)的一方 40. OneToMany(mappedBy = "group", cascade = CascadeType.ALL , fetch = FetchType.LAZY) 41.
10、160;public Set<User> getUsers() 42. return users; 43. 44. 45. public void setUsers(Set<User> users)
11、; 46. this.users = users; 47. 48. User類如下:java view plain copy1. package com.chen.hibernate.ormapping; 2. 3. import javax.persistence.C
12、ascadeType; 4. import javax.persistence.Entity; 5. import javax.persistence.FetchType; 6. import javax.persistence.GeneratedValue; 7. import javax.persistence.Id; 8. import javax.persistence.JoinColumn; 9. imp
13、ort javax.persistence.ManyToOne; 10. import javax.persistence.Table; 11. 12. Entity 13. Table(name = "t_user") 14. public class User 15. private int id;&
14、#160; 16. private String name; 17. private Group group; 18. 19. Id 20. GeneratedValue 21. public
15、60;int getId() 22. return id; 23. 24. 25. public void setId(int id) 26.
16、160; this.id = id; 27. 28. 29. public String getName() 30. return name; 31.
17、;32. 33. public void setName(String name) 34. = name; 35. 36. 37. /設(shè)置fetch為lazy,多
18、的一方默認(rèn)問eager 38. ManyToOne(cascade = CascadeType.ALL , fetch = FetchType.EAGER) 39. JoinColumn(name = "groupId") 40. public Group
19、getGroup() 41. return group; 42. 43. 44. public void setGroup(Group group) 45.
20、 this.group = group; 46. 47. junit測(cè)試類java view plain copy1. package com.chen.hibernate.ormapping; 2. 3. import org.hibernate.Session; 4. import org.hibernate.Ses
21、sionFactory; 5. import org.hibernate.cfg.AnnotationConfiguration; 6. import org.hibernate.tool.hbm2ddl.SchemaExport; 7. import org.junit.AfterClass; 8. import org.junit.BeforeClass; 9. import org.junit.Test; 1
22、0. 11. public class CRUDTest 12. private static SessionFactory sessionFactory = null; 13. 14. BeforeClass 15. public static
23、160;void beforeClass() 16. new SchemaExport(new AnnotationConfiguration().configure().create( 17. false, tru
24、e); 18. sessionFactory = new AnnotationConfiguration().configure() 19. .buildSessionFactory(); 20.
25、60; 21. 22. Test 23. public void testSaveUser() 24. User user = new User(); 25.
26、160; user.setName("u1"); 26. Group group = new Group(); 27. group.setName("g1"); 28. 29. &
27、#160; / 這里僅僅把group加到user中,而不需要group.getUsers().add(user);把當(dāng)前的對(duì)象加入到group的set里 30. user.setGroup(group); 31. 32. Session sessio
28、n = sessionFactory.getCurrentSession(); 33. session.beginTransaction(); 34. session.save(user); 35. session.getTr
29、ansaction().commit(); 36. 37. 38. / 再看看save被主導(dǎo)的一方會(huì)如何。 39. Test 40. public void testSaveGroup() 41.
30、0; / 先new兩個(gè)user,一個(gè)group,然后把user加到group中 42. User user = new User(); 43. user.setName("u1"); 44.
31、;45. User user2 = new User(); 46. user2.setName("u2"); 47. Group group = new Group()
32、; 48. group.setName("g1"); 49. group.getUsers().add(user); 50. group.getUsers().add(user2); 51.
33、 52. / 注意,雖然兩邊都是級(jí)聯(lián)的方式,但這裡的user也要把group設(shè)一下,不然,save(group)的時(shí)候,user表中的 53. / groupId字段仍是null 54. user.setGroup(group);
34、0; 55. user2.setGroup(group); 56. 57. Session session = sessionFactory.getCurrentSession(); 58. sessio
35、n.beginTransaction(); 59. 60. /* 61. * 此時(shí)在save(group)的時(shí)候,由于級(jí)聯(lián)關(guān)系會(huì)先插入里面的兩個(gè)user,而此時(shí)如果不寫上面的 62.
36、160; * user.setGroup(group); user2.setGroup(group); 63. * 這兩句,user對(duì)應(yīng)表里面的groupId字段都將為空 64. */ 65.
37、 session.save(group); 66. session.getTransaction().commit(); 67. 68. 69. AfterClass 70. public static
38、 void afterClass() 71. sessionFactory.close(); 72. 73. 74. 先來個(gè)結(jié)論,什么時(shí)候t_user中的外鍵groupId才會(huì)參考t_group主鍵取得值?結(jié)論:這里的關(guān)系的主導(dǎo)方向是User->Group,只有當(dāng)級(jí)聯(lián)的方向也是從User->Gr
39、oup時(shí),才會(huì)設(shè)置這個(gè)外鍵的值。這個(gè)結(jié)論可以參考這樣的圖:看下實(shí)驗(yàn)結(jié)果,先測(cè)試運(yùn)行testSaveUser方法,運(yùn)行結(jié)果對(duì)于的t_group和t_user表如下,此時(shí)數(shù)據(jù)插入都是正常的。插入的過程是應(yīng)該是這樣的,由于save的是user,所以先插t_user表,由于t_user表和t_group表的主鍵id字段都是由同一個(gè)sequence產(chǎn)生的,所以這里由主鍵id字段也可以看出先是插入了t_user,t_user中有g(shù)roup對(duì)象且不是null(要是null的話,即使設(shè)了級(jí)聯(lián),也不會(huì)再插t_group表了,沒東西插入?。。?,由于User設(shè)置了級(jí)聯(lián),所以此時(shí)又插入了t_group表,因?yàn)榧?jí)聯(lián)的方
40、向?yàn)閁ser->Group,和關(guān)系的主導(dǎo)方向相同,所以這里t_user表的groupId字段參考了t_group表的主鍵字段2。t_user表t_group表在測(cè)試下testSaveGroup,若先注掉user.setGroup(group);user2.setGroup(group);這兩行,也就是說就像testSaveUser中一樣,只是簡(jiǎn)單的把user加到group里的集合set里,會(huì)怎樣呢?測(cè)試的結(jié)果如下:t_user表t_group表可以看到t_user表的groupId字段為空,為什么呢?同樣按照上面的分析思路,由于save的是group,所以先插入t_group表,插入1,
41、g1,而group對(duì)象中有一個(gè)user的集合,里面有兩個(gè)user,由于級(jí)聯(lián),此時(shí)就會(huì)插入t_user表,此時(shí)級(jí)聯(lián)的方向?yàn)镚roup->User,這個(gè)級(jí)聯(lián)方向不會(huì)設(shè)置t_user中的groupId,因?yàn)樯厦孀⑨尩袅藆ser.setGroup(group);user2.setGroup(group);這兩句,也就是說這兩個(gè)user中的group都為null,所以在插入t_user表的時(shí)候不會(huì)產(chǎn)生級(jí)聯(lián)再插入t_group表了,所以t_user中兩條記錄的groupId字段都為空。把user.setGroup(group);user2.setGroup(group);這兩句加上后,運(yùn)行的結(jié)果如下
42、,可以看到t_user表的groupId字段為1,參考了t_group的主鍵。這個(gè)執(zhí)行的過程是這樣的,先將group對(duì)象插入t_group表為1,g1,由于級(jí)聯(lián)(Group->User)會(huì)將user和user2兩個(gè)對(duì)象插入t_user表,當(dāng)插user對(duì)象時(shí)候,user中的group字段不是一個(gè)null(是之前的group對(duì)象),所以又會(huì)發(fā)生級(jí)聯(lián),方向?yàn)椋║ser->Group),此時(shí)又會(huì)將這個(gè)group對(duì)象插入到t_group表,將插入后的主鍵id的值設(shè)為t_user中插入user對(duì)象時(shí)的groupId的值,但是會(huì)發(fā)現(xiàn)這個(gè)group對(duì)象剛才已經(jīng)插入過了,所以只是簡(jiǎn)單的將剛才插入gr
43、oup對(duì)象時(shí)的產(chǎn)生的主鍵id的值1給剛才的groupId值,最終將user插入到t_user中的記錄為2,u1,1,上面的級(jí)聯(lián)到重復(fù)插入那個(gè)group的時(shí)候就停止了,不會(huì)無窮的遞歸的進(jìn)行下去。插入user2對(duì)象時(shí),過程一樣。可以從這個(gè)過程得到兩個(gè)結(jié)論:(1)在同一個(gè)session中,同一個(gè)對(duì)象不會(huì)在數(shù)據(jù)庫中插入兩條不同的記錄。(2)級(jí)聯(lián)停止的條件為,對(duì)象里的關(guān)聯(lián)字段為null或在一個(gè)表插隊(duì)的對(duì)象已經(jīng)被插入過。t_user表t_group表若把testSaveGroup()改為如下:java view plain copy1. Test
44、160;
45、160; 2. public void testSaveGroup()
46、0; 3. / 先new兩個(gè)user,一個(gè)group,然后把user加到group中
47、160; 4. User user = new User();
48、0; 5. user.setName("u1");
49、160; 6.
50、;
51、; 7. User user2 = new User();
52、 8. user2.setName("u2");
53、60; 9. Group group = new Group();
54、160; 10. group.setName("g1");
55、0; 11.
56、 group.getUsers().add(user);
57、60; 12. group.getUsers().add(user2); &
58、#160; 13.
59、60; 14. / 新new一個(gè)group2,把它加到user2對(duì)象里面,下面save(group)會(huì)發(fā)生什么呢?
60、; 15. Group group2 = new Group();
61、160; 16. group2.setName("g2");
62、60; 17. user2.setGroup(group2);
63、 18.
64、160;
65、160; 19. Session session = sessionFactory.getCurrentSession(); 20.
66、0; session.beginTransaction(); &
67、#160;21. session.save(group); &
68、#160; 22. session.getTransaction().commit();
69、; 23. &
70、#160; 再new一個(gè)group2,然后set到user2的group屬性,這時(shí)測(cè)試會(huì)怎么樣?可以設(shè)想一下,結(jié)果應(yīng)該是這樣的,由于save(group),所以先插入t_group表,在t_group中插入一條記錄為1,g1,因?yàn)?/p>
71、t_group中有一個(gè)集合,里面有兩個(gè)user且都是非null的,所以會(huì)發(fā)生級(jí)聯(lián)(方向?yàn)镚roup->User),會(huì)插入這兩個(gè)user,這時(shí)候到底先插入哪一個(gè)user是不一定的,因?yàn)間roup中是個(gè)集合,假設(shè)按照add的順序先插user,后插user2,那么在t_user表中會(huì)先插入一條記錄2,u1,?,此時(shí)插入這條記錄的時(shí)候由于user中的group為null,所以不會(huì)發(fā)生級(jí)聯(lián),所以這里記錄的groupId為null,所以完整的是2,u1,null。接著插入user2對(duì)象,插入的記錄為3,u2,?,這里的?暫時(shí)不定,user2中的group為非null(設(shè)了group2對(duì)象,注意這個(gè)g
72、roup2之前沒有被插入過),所以會(huì)發(fā)生級(jí)聯(lián)插入t_group表,所以在t_group表中會(huì)插入4,g2,這條記錄是由插入3,u2,?級(jí)聯(lián)過來的(方向?yàn)閁ser->Group),所以上面的?會(huì)參考這條記錄的主鍵4,接著在t_group中插入4,g2的時(shí)候,因?yàn)檫@個(gè)group對(duì)象的集合set為null,所以不會(huì)發(fā)生級(jí)聯(lián),此時(shí)級(jí)聯(lián)就收斂了。最終t_group和t_user表的情況應(yīng)該是這樣。t_user表2,u1,null3,u2,4t_group表1,g14,g2測(cè)試的結(jié)果如下,和預(yù)期是一樣的。t_user表:t_group表:以上分析的是一對(duì)多的雙向關(guān)聯(lián),采用這種分析的思路看能不能解釋多
73、對(duì)多的雙向關(guān)聯(lián)的結(jié)果,做如下實(shí)驗(yàn),有兩個(gè)類Teacher和Student類,他們時(shí)間是多對(duì)多的關(guān)系。多對(duì)多的關(guān)系會(huì)映射成三張表,一張中間表,這里產(chǎn)生的三張表為teacher(id,name),student(id,name),t_s(teacher_id,student_id),teacher_id和student_id作為t_s的聯(lián)合主鍵,其中teacher_id參考了teacher表中的主鍵id,student_id參考了student表的主鍵id字段。其中關(guān)系的主導(dǎo)方向?yàn)門eacher->Student,此時(shí)中間表t_s可以看成teacher表中的一部分,只不過如果真的作為teac
74、her表的一部分,teacher表中會(huì)多出很多冗余的字段,所以把它獨(dú)立出來,只是我們可以參考一對(duì)多雙向關(guān)聯(lián)的情況下那樣看它。所以只有級(jí)聯(lián)的方向?yàn)閠eacher->student方向才會(huì)插入t_s表。Teacher類:java view plain copy1. package com.chen.hibernate.ormapping; 2. 3. import java.util.HashSet; 4. import java.util.Set; 5
75、. 6. import javax.persistence.CascadeType; 7. import javax.persistence.Entity; 8. import javax.persistence.GeneratedValue; 9. import javax.persistence.Id; 10. import javax.persistence.JoinColumn; 11. import
76、160;javax.persistence.JoinTable; 12. import javax.persistence.ManyToMany; 13. 14. Entity 15. public class Teacher 16. private int id; 17. private Str
77、ing name; 18. private Set<Student> students = new HashSet<Student>(); 19. 20. Id 21. GeneratedValue 22. pu
78、blic int getId() 23. return id; 24. 25. 26. public void setId(int id) 27. &
79、#160; this.id = id; 28. 29. 30. public String getName() 31. return name; 32.
80、0; 33. 34. public void setName(String name) 35. = name; 36. 37. 38. ManyToMa
81、ny(cascade = CascadeType.ALL) 39. JoinTable(name = "t_s", joinColumns = JoinColumn(name = "teacher_id", referencedColumnName = "id"), inverseJoinColumns = JoinC
82、olumn(name = "student_id", referencedColumnName = "id") 40. public Set<Student> getStudents() 41. return students; 42.
83、0; 43. 44. public void setStudents(Set<Student> students) 45. this.students = students; 46.
84、47. Student類:java view plain copy1. package com.chen.hibernate.ormapping; 2. 3. import java.util.HashSet; 4. import java.util.Set; 5. 6. import javax.persistence.CascadeType; 7. import
85、javax.persistence.Entity; 8. import javax.persistence.GeneratedValue; 9. import javax.persistence.Id; 10. import javax.persistence.ManyToMany; 11. 12. Entity 13. public class Student 14.
86、0; private int id; 15. private String name; 16. private Set<Teacher> teachers = new HashSet<Teacher>(); 17. 18.
87、60;Id 19. GeneratedValue 20. public int getId() 21. return id; 22. 23. 24.
88、0; public void setId(int id) 25. this.id = id; 26. 27. 28. public String getName() 29.
89、160; return name; 30. 31. 32. public void setName(String name) 33. = name;
90、60; 34. 35. 36. / 設(shè)置Student類為被主導(dǎo)的類 37. ManyToMany(mappedBy = "students", cascade = CascadeType.ALL) 38. public
91、60;Set<Teacher> getTeachers() 39. return teachers; 40. 41. 42. public void setTeachers(Set<Teacher> teachers)
92、 43. this.teachers = teachers; 44. 45. junit測(cè)試類java view plain copy1. package com.chen.hibernate.ormapping; 2. 3. import org.hibe
93、rnate.Session; 4. import org.hibernate.SessionFactory; 5. import org.hibernate.cfg.AnnotationConfiguration; 6. import org.hibernate.tool.hbm2ddl.SchemaExport; 7. import org.junit.AfterClass; 8. import org.junit.BeforeCla
94、ss; 9. import org.junit.Test; 10. 11. public class testMany2ManyCRUD 12. private static SessionFactory sessionFactory = null; 13. 14. Befo
95、reClass 15. public static void beforeClass() 16. new SchemaExport(new AnnotationConfiguration().configure().create( 17.
96、160; false, true); 18. sessionFactory = new AnnotationConfiguration().configure() 19.
97、; .buildSessionFactory(); 20. 21. 22. Test 23. public void testSaveStudent() 24. /先new兩個(gè)st
98、udent和兩個(gè)teacher,然后把兩個(gè)student分別加到兩個(gè)teacher里 25. Student student = new Student(); 26. student.setName("s1"); 27.
99、 Student student2 = new Student(); 28. student2.setName("s2"); 29. 30. Teacher teacher = new Teacher();
100、 31. teacher.setName("t1"); 32. Teacher teacher2 = new Teacher(); 33. teacher2.setName("
101、t2"); 34. student.getTeachers().add(teacher); 35. student.getTeachers().add(teacher2); 36. 37. student2.ge
102、tTeachers().add(teacher); 38. student2.getTeachers().add(teacher2); 39. 40. /把這兩個(gè)teacher分別加到兩個(gè)student里,這是必須的,不然中間表t_s中不會(huì)有記錄 41. &
103、#160; for (Teacher t : student.getTeachers() 42. t.getStudents().add(student); 43. t.getStudents(
104、).add(student2); 44. 45. 46. for (Teacher t : student2.getTeachers() 47.
105、; t.getStudents().add(student); 48. t.getStudents().add(student2); 49. 50. 51.
106、160;Session session = sessionFactory.getCurrentSession(); 52. session.beginTransaction(); 53. session.save(student); 54.
107、; session.save(student2); 55. session.getTransaction().commit(); 56. 57. 58. Test 59. public void test
108、SaveTeacher() 60. /new兩個(gè)teacher和student,在save(teacher)時(shí),只需把兩個(gè)student分別加到兩個(gè)teacher中就可以了。 61. /中間表t_s中也有數(shù)據(jù) 62. Teacher teacher = new Teacher(); 63. teacher.setName("t1"); 64. Teacher teacher2 = new Teach
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 第九課自定義函數(shù)教學(xué)設(shè)計(jì)2023-2024學(xué)年青島版(2019)信息技術(shù)第三冊(cè)
- 2024年武漢江岸區(qū)某國有企業(yè)招聘投資團(tuán)隊(duì)成員5人筆試參考題庫附帶答案詳解
- 安徽省黃山地區(qū)2023-2024學(xué)年八年級(jí)下學(xué)期期末語文試題
- 第一單元第六課三、《AVERAGEIF函數(shù)》教學(xué)設(shè)計(jì) 2023-2024學(xué)年新世紀(jì)版(2018)初中信息技術(shù)七年級(jí)下冊(cè)
- 第六單元碳和碳的氧化物單元整體教學(xué)設(shè)計(jì)-2023-2024學(xué)年九年級(jí)化學(xué)人教版上冊(cè)
- 2025年貴州航空職業(yè)技術(shù)學(xué)院?jiǎn)握新殬I(yè)傾向性測(cè)試題庫必考題
- 配電線路工專業(yè)復(fù)習(xí)題含參考答案
- 護(hù)理藥理學(xué)題庫+參考答案
- 中醫(yī)兒科學(xué)模擬考試題含答案
- 10《老人與?!方虒W(xué)設(shè)計(jì) 2024-2025學(xué)年統(tǒng)編版高中語文選擇性必修上冊(cè)
- 尺寸鏈的計(jì)算表格
- 夏玉米套種辣椒技術(shù)
- 學(xué)術(shù)規(guī)范與寫作課件
- 2023年江蘇省南京市市場(chǎng)監(jiān)督管理局所屬事業(yè)單位招聘5人(共500題含答案解析)筆試歷年難、易錯(cuò)考點(diǎn)試題含答案附詳解
- 絕緣電阻測(cè)試儀安全操作規(guī)程
- DB6101T 197-2022 藤蔓類尾菜堆肥技術(shù)規(guī)程
- 《生僻字》歌詞(帶拼音解釋)
- 西藏房屋建筑工程竣工材料全套表格
- 品管圈基本知識(shí)
- 物業(yè)項(xiàng)目保潔服務(wù)質(zhì)量保證及安全保障措施(標(biāo)書專用)參考借鑒范本
- 量子力學(xué)英文課件格里菲斯Chapter4
評(píng)論
0/150
提交評(píng)論