天天看點

hibernate之關于關聯映射的綜合應用

1、關聯映射如何處理業務邏輯

2、如何指定中間表

3、如何進行級聯操作

4、如何解決Hibenrate建表過程中主鍵錯亂問題

現在有三張表

Student(學生表),Course(課程表),Score(學生,課程,分數,表)

那麼我們分析業務邏輯可知,學生和課程是多對多的關系,學生和分數表是一對多的關系,課程和分數也是一對多的關系。

直接看Annotations配置,在這裡我所有的配置都是雙向關聯,這樣在分數,課程,學生,之中,可以任意找到彼此!

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

<code>@Entity</code>

<code>@Table</code><code>(name=</code><code>"c_course"</code><code>)</code>

<code>public</code> <code>class</code> <code>Course {</code>

<code>    </code><code>private</code> <code>Integer id;</code>

<code>    </code><code>private</code> <code>String coursename;</code>

<code>    </code><code>private</code> <code>Set&lt;Student&gt; students=</code><code>new</code> <code>HashSet&lt;Student&gt;();</code>

<code>    </code><code>private</code> <code>Set&lt;Score&gt; scores=</code><code>new</code> <code>HashSet&lt;Score&gt;();</code>

<code>    </code> 

<code>    </code><code>@OneToMany</code><code>(mappedBy=</code><code>"course"</code><code>)</code><code>//必須指定關系由多的一方維護</code>

<code>    </code><code>public</code> <code>Set&lt;Score&gt; getScores() {</code>

<code>        </code><code>return</code> <code>scores;</code>

<code>    </code><code>}</code>

<code>    </code><code>public</code> <code>void</code> <code>setScores(Set&lt;Score&gt; scores) {</code>

<code>        </code><code>this</code><code>.scores = scores;</code>

<code>    </code><code>@ManyToMany</code><code>//指定中間表是s_score</code>

<code>    </code><code>@JoinTable</code><code>(name=</code><code>"s_score"</code><code>,joinColumns={</code><code>@JoinColumn</code><code>(name=</code><code>"course_id"</code><code>)},</code>

<code>            </code><code>inverseJoinColumns={</code><code>@JoinColumn</code><code>(name=</code><code>"student_id"</code><code>)})</code>

<code>    </code><code>public</code> <code>Set&lt;Student&gt; getStudents() {</code>

<code>        </code><code>return</code> <code>students;</code>

<code>    </code><code>public</code> <code>void</code> <code>setStudents(Set&lt;Student&gt; students) {</code>

<code>        </code><code>this</code><code>.students = students;</code>

<code>    </code><code>@Id</code>

<code>    </code><code>@GeneratedValue</code>

<code>    </code><code>public</code> <code>Integer getId() {</code>

<code>        </code><code>return</code> <code>id;</code>

<code>    </code><code>public</code> <code>void</code> <code>setId(Integer id) {</code>

<code>        </code><code>this</code><code>.id = id;</code>

<code>    </code><code>@Column</code><code>(name=</code><code>"c_coursename"</code><code>)</code>

<code>    </code><code>public</code> <code>String getCoursename() {</code>

<code>        </code><code>return</code> <code>coursename;</code>

<code>    </code><code>public</code> <code>void</code> <code>setCoursename(String coursename) {</code>

<code>        </code><code>this</code><code>.coursename = coursename;</code>

<code>}</code>

(課程表Course)

41

<code>@Table</code><code>(name=</code><code>"t_student"</code><code>)</code>

<code>public</code> <code>class</code> <code>Student {</code>

<code>    </code><code>private</code> <code>String name;</code>

<code>    </code><code>private</code> <code>Set&lt;Course&gt; courses=</code><code>new</code> <code>HashSet&lt;Course&gt;();</code>

<code>    </code><code>@OneToMany</code><code>(mappedBy=</code><code>"student"</code><code>)</code>

<code>    </code><code>@ManyToMany</code>

<code>    </code><code>@JoinTable</code><code>(name=</code><code>"s_score"</code><code>,joinColumns={</code><code>@JoinColumn</code><code>(name=</code><code>"student_id"</code><code>)},</code>

<code>            </code><code>inverseJoinColumns={</code><code>@JoinColumn</code><code>(name=</code><code>"course_id"</code><code>)})</code>

<code>    </code><code>public</code> <code>Set&lt;Course&gt; getCourses() {</code>

<code>        </code><code>return</code> <code>courses;</code>

<code>    </code><code>public</code> <code>void</code> <code>setCourses(Set&lt;Course&gt; courses) {</code>

<code>        </code><code>this</code><code>.courses = courses;</code>

<code>    </code><code>@Column</code><code>(name=</code><code>"s_name"</code><code>)</code>

<code>    </code><code>public</code> <code>String getName() {</code>

<code>        </code><code>return</code> <code>name;</code>

<code>    </code><code>public</code> <code>void</code> <code>setName(String name) {</code>

<code>        </code><code>this</code><code>.name = name;</code>

(Student學生表)

<code>@Table</code><code>(name=</code><code>"s_score"</code><code>)</code>

<code>public</code> <code>class</code> <code>Score {</code>

<code>    </code><code>private</code> <code>String score;</code>

<code>    </code><code>private</code> <code>Student student;</code>

<code>    </code><code>private</code> <code>Course course;</code>

<code>    </code><code>@ManyToOne</code><code>(cascade={CascadeType.ALL})</code><code>//配置級聯操作</code>

<code>    </code><code>@JoinColumn</code><code>(name=</code><code>"student_id"</code><code>)</code>

<code>    </code><code>public</code> <code>Student getStudent() {</code>

<code>        </code><code>return</code> <code>student;</code>

<code>    </code><code>public</code> <code>void</code> <code>setStudent(Student student) {</code>

<code>        </code><code>this</code><code>.student = student;</code>

<code>    </code><code>@ManyToOne</code><code>(cascade={CascadeType.ALL})</code>

<code>    </code><code>@JoinColumn</code><code>(name=</code><code>"course_id"</code><code>)</code>

<code>    </code><code>public</code> <code>Course getCourse() {</code>

<code>        </code><code>return</code> <code>course;</code>

<code>    </code><code>public</code> <code>void</code> <code>setCourse(Course course) {</code>

<code>        </code><code>this</code><code>.course = course;</code>

<code>    </code><code>@Column</code><code>(name=</code><code>"s_score"</code><code>)</code>

<code>    </code><code>public</code> <code>String getScore() {</code>

<code>        </code><code>return</code> <code>score;</code>

<code>    </code><code>public</code> <code>void</code> <code>setScore(String score) {</code>

<code>        </code><code>this</code><code>.score = score;</code>

(分數表,也是中間關聯表,Score)

那麼問題來了,采用Hibernate自動建表,我們看一下建表語句

<code>12:11:08,169 DEBUG SchemaExport:415 - </code>

<code>    </code><code>create</code> <code>table</code> <code>c_course (</code>

<code>        </code><code>id </code><code>integer</code> <code>not</code> <code>null</code> <code>auto_increment,</code>

<code>        </code><code>c_coursename </code><code>varchar</code><code>(255),</code>

<code>        </code><code>primary</code> <code>key</code> <code>(id)</code>

<code>    </code><code>)</code>

<code>12:11:08,333 DEBUG SchemaExport:415 - </code>

<code>    </code><code>create</code> <code>table</code> <code>s_score (</code>

<code>        </code><code>id </code><code>integer</code> <code>not</code> <code>null</code><code>,</code>

<code>        </code><code>s_score </code><code>varchar</code><code>(255),</code>

<code>        </code><code>course_id </code><code>integer</code><code>,</code>

<code>        </code><code>student_id </code><code>integer</code> <code>not</code> <code>null</code> <code>auto_increment,</code>

<code>        </code><code>primary</code> <code>key</code> <code>(student_id, course_id)</code>

<code>12:11:08,455 DEBUG SchemaExport:415 - </code>

<code>    </code><code>create</code> <code>table</code> <code>t_student (</code>

<code>        </code><code>s_name </code><code>varchar</code><code>(255),</code>

我們發現在建表是Hibernate預設将student_id和course_id聯合作為主鍵使用,且student_id還是自增

這樣顯然是不對的,在這裡我也實在想不到,好的辦法,智能采用一個笨的辦法,手動改回來!

大家最好是采用工具操作,因為,你直接create的話,student_id和course_id關聯不上student,course的主鍵ID

ok,到這裡,我們的建表基本完成,下面JunitTest

<code>    </code><code>@Test</code>

<code>    </code><code>public</code> <code>void</code> <code>add(){</code>

<code>        </code><code>try</code> <code>{</code>

<code>            </code><code>Configuration cfg=</code><code>new</code> <code>Configuration();</code>

<code>            </code><code>cfg.configure();</code>

<code>            </code><code>SessionFactory  sessionFactory=cfg.buildSessionFactory();</code>

<code>            </code><code>Session session=sessionFactory.openSession();</code>

<code>            </code><code>session.beginTransaction();</code>

<code>            </code><code>Student student1=</code><code>new</code> <code>Student();</code>

<code>            </code><code>student1.setName(</code><code>"張三1"</code><code>);</code>

<code>//          Student student2=new Student();</code>

<code>//          student2.setName("李四");</code>

<code>            </code><code>Course c1=</code><code>new</code> <code>Course();</code>

<code>            </code><code>c1.setCoursename(</code><code>"數學1"</code><code>);</code>

<code>            </code><code>Course c2=</code><code>new</code> <code>Course();</code>

<code>            </code><code>c2.setCoursename(</code><code>"國文1"</code><code>);</code>

<code>//          session.save(student1);</code>

<code>//          session.save(c1);</code>

<code>//          session.save(student2);</code>

<code>//          session.save(c2);</code>

<code>            </code><code>Score score=</code><code>new</code> <code>Score();</code>

<code>            </code><code>score.setScore(</code><code>"901"</code><code>);</code>

<code>            </code><code>score.setCourse(c1);</code>

<code>            </code><code>score.setStudent(student1);</code>

<code>            </code><code>//張三數學90分</code>

<code>            </code><code>session.save(score);</code>

<code>            </code><code>Score score2=</code><code>new</code> <code>Score();</code>

<code>            </code><code>score2.setCourse(c2);</code>

<code>            </code><code>score2.setScore(</code><code>"100"</code><code>);</code>

<code>            </code><code>score2.setStudent(student1);</code>

<code>            </code><code>session.save(score2);</code>

<code>            </code><code>session.getTransaction().commit();</code>

<code>            </code><code>session.close();</code>

<code>            </code><code>sessionFactory.close();</code>

<code>        </code><code>} </code><code>catch</code> <code>(HibernateException e) {</code>

<code>            </code><code>e.printStackTrace();</code>

<code>        </code><code>}</code>

ok,大家可以看出,為什麼我們最後隻需要儲存score就行呢?沒有session.save()student和course,為什麼也能直接儲存資料庫中?這就是

<code>cascade={CascadeType.ALL}</code>

級聯操作,當然我這裡配置的是ALL,其實還有4個參數,大家可以自己慢慢研究!

以上添加成功,那麼我們直接load試一下

<code>public</code> <code>void</code> <code>findTest(){</code>

<code>        </code><code>Configuration cfg=</code><code>new</code> <code>Configuration();</code>

<code>        </code><code>cfg.configure();</code>

<code>        </code><code>SessionFactory  sessionFactory=cfg.buildSessionFactory();</code>

<code>        </code><code>Session s=sessionFactory.openSession();</code>

<code>        </code><code>s.beginTransaction();</code>

<code>        </code><code>Student student=(Student)s.load(Student.</code><code>class</code><code>, </code><code>2</code><code>);</code>

<code>        </code><code>System.out.println(</code><code>"學生姓名"</code><code>+student.getName());</code>

<code>        </code><code>for</code><code>(Course course:student.getCourses()){</code>

<code>            </code><code>System.out.print(</code><code>"--------"</code><code>+</code><code>"課程名稱"</code><code>+course.getCoursename());</code>

<code>            </code><code>for</code><code>(Score score:course.getScores()){</code>

<code>                </code><code>System.out.println(</code><code>"--------"</code><code>+</code><code>"課程分數"</code><code>+score.getScore());</code>

<code>            </code><code>}</code>

<code>        </code><code>s.getTransaction().commit();</code>

<code>        </code><code>s.close();</code>

<code>        </code><code>sessionFactory.close();</code>

也沒問題

update呢?

<code>public</code> <code>void</code>    <code>update(){</code>

<code>        </code><code>Student student=(Student)s.load(Student.</code><code>class</code><code>,</code><code>1</code><code>);</code>

<code>        </code><code>//我們現在把查詢出來國文成績改為0分</code>

<code>            </code><code>System.out.println(course.getCoursename());</code>

<code>            </code><code>if</code><code>(</code><code>"國文"</code><code>.equals(course.getCoursename())){</code>

<code>                </code><code>for</code><code>(Score score:course.getScores()){</code>

<code>                    </code><code>if</code><code>(score.getStudent().getId().equals(student.getId())){</code>

<code>                        </code><code>score.setScore(</code><code>"0"</code><code>);</code>

<code>                        </code><code>s.update(score);</code>

<code>                    </code><code>}</code>

<code>                </code><code>}</code>

<code>        </code><code>} </code>

删除?

<code>@Test</code>

<code>    </code><code>public</code> <code>void</code> <code>deleteObj(){</code>

<code>        </code><code>Student student=(Student)s.load(Student.</code><code>class</code><code>,</code><code>3</code><code>);</code>

<code>        </code><code>s.delete(student);</code>

<code>        </code> 

ok,到這裡基本上,完成Hibernate關聯映射的基本操作!

注意,多對多删除的時候,我們一般删除的是中間表資料?但是往往由于外鍵關聯的關系,Hibernate會删除另一張表中的資料來解除關聯關系,這就不對了!後續再探讨!

本文轉自 小夜的傳說 51CTO部落格,原文連結:http://blog.51cto.com/1936625305/1569149,如需轉載請自行聯系原作者