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<Student> students=</code><code>new</code> <code>HashSet<Student>();</code>
<code> </code><code>private</code> <code>Set<Score> scores=</code><code>new</code> <code>HashSet<Score>();</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<Score> 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<Score> 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<Student> getStudents() {</code>
<code> </code><code>return</code> <code>students;</code>
<code> </code><code>public</code> <code>void</code> <code>setStudents(Set<Student> 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<Course> courses=</code><code>new</code> <code>HashSet<Course>();</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<Course> getCourses() {</code>
<code> </code><code>return</code> <code>courses;</code>
<code> </code><code>public</code> <code>void</code> <code>setCourses(Set<Course> 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,如需轉載請自行聯系原作者