Hibernate中的關(guān)聯(lián)(Association)映射主要有三種:一對(duì)一關(guān)聯(lián),一對(duì)多(或多對(duì)一)關(guān)聯(lián),多對(duì)多關(guān)聯(lián)。每種關(guān)聯(lián)都可以分為單向和雙向兩種。
前面文章已經(jīng)說(shuō)了一對(duì)一關(guān)聯(lián)和一對(duì)多(或多對(duì)一)關(guān)聯(lián),這次談?wù)劧鄬?duì)多關(guān)聯(lián)。至于環(huán)境設(shè)置,可以參考這個(gè)系列的前面幾篇文章。
這里有兩個(gè)類,一個(gè)是Student,一個(gè)是Course。一個(gè)學(xué)生可以選擇多個(gè)課程,而一個(gè)課程也可以被多個(gè)學(xué)生選擇,這樣就構(gòu)成了多對(duì)多的關(guān)聯(lián)。這個(gè)關(guān)聯(lián)是單向的,由Student控制的。
1. 創(chuàng)建項(xiàng)目
· 新建一個(gè)Java項(xiàng)目:AssociationMapping,注意選中“創(chuàng)建單獨(dú)的源文件夾和輸出文件夾”,同時(shí)添加“用戶庫(kù)”:hibernate。
2. 編寫(xiě)類文件
· 新建一個(gè)類,包名:javamxj.hibernate.association.many2many,類名:Student。
package javamxj.hibernate.association.many2many;import java.util.HashSet;import java.util.Set;/** * @hibernate.class table = "T_Student" */public class Student { private Long id; private Set courses=new HashSet(); private String name; public Student() {} public Student(String name) { this.name = name; } /** * @hibernate.id * column="ID" * generator-class="hilo" * unsaved-value="null" */ public Long getId() {return id;} public void setId(Long id) {this.id = id;} /** * @hibernate.set * table="students_in_course" * cascade="save-update" * @hibernate.collection-many-to-many * column="fk_course" * class="javamxj.hibernate.association.many2many.Course" * @hibernate.collection-key * column="fk_student" */ public Set getCourses() {return courses;} public void setCourses(Set courses) {this.courses = courses;} /** * @hibernate.property length = "16" */ public String getName() {return name;} public void setName(String name) {this.name = name;}}
· 重點(diǎn)看看有關(guān)多對(duì)多關(guān)聯(lián)的XDoclet標(biāo)記。
· 同樣,在這個(gè)包下新建一個(gè)Course類。
package javamxj.hibernate.association.many2many;/** * @hibernate.class table = "T_Course" */public class Course { private Long id; private String description; public Course(){} public Course(String description) { this.description = description; } /** * @hibernate.id * column="ID" * generator-class="hilo" * unsaved-value="null" */ public Long getId() {return id;} public void setId(Long id) {this.id = id;} /** * @hibernate.property * length = "40" */ public String getDescription() {return description;} public void setDescription(String description) {this.description = description;}}
· 雙擊“generate-hbm”任務(wù),會(huì)發(fā)現(xiàn)在包中產(chǎn)生了Student.hbm.xml和Course.hbm.xml文件,在src目錄下會(huì)多了一個(gè)hibernate.cfg.xml文件,如果沒(méi)有,按F5鍵刷新一下。
· 看看Student類的映射文件中的有關(guān)多對(duì)多關(guān)聯(lián)部分:
<set
name="courses"
table="students_in_course"
lazy="false"
inverse="false"
cascade="save-update"
sort="unsorted"
>
<key
column="fk_student"
>
</key>
<many-to-many
class="javamxj.hibernate.association.many2many.Course"
column="fk_course"
outer-join="auto"
/>
</set>
· 上面的lazy="false"表示不采用延遲加載,inverse="false"表示主控方在Student端。
· 這里沒(méi)有直接建立Student類和Course類的多對(duì)多關(guān)聯(lián),而是通過(guò)一個(gè)中介類來(lái)反映多對(duì)多的關(guān)聯(lián),這個(gè)中介類分別與Student類和Course類構(gòu)成多對(duì)一關(guān)聯(lián),這個(gè)中介類映射的表通過(guò) table="students_in_course" 獲得。這個(gè)表有兩個(gè)字段,分別是 fk_student、fk_course 。
· 運(yùn)行MySql服務(wù)器,然后雙擊“schemaexport”任務(wù),在項(xiàng)目根目錄下,會(huì)產(chǎn)生一個(gè)“schema-export.sql”文件。
· 切換到數(shù)據(jù)庫(kù)中,會(huì)發(fā)現(xiàn)已經(jīng)自動(dòng)產(chǎn)生了數(shù)據(jù)表T_Student、T_Course 和 students_in_course。
4. 測(cè)試程序
· 好了,在包javamxj.hibernate.association.one2one下新建一個(gè)Demo.java文件。
/* * Hibernate - 關(guān)聯(lián)(Association)映射(多對(duì)多) * 創(chuàng)建日期 2005-5-1 * @author javamxj(分享java快樂(lè)) * @link Blog: htpp://blog.csdn.net/javamxj/ * htpp://javamxj.mblogger.cn */package javamxj.hibernate.association.many2many;import net.sf.hibernate.HibernateException;import net.sf.hibernate.Session;import net.sf.hibernate.SessionFactory;import net.sf.hibernate.Transaction;import net.sf.hibernate.cfg.Configuration;public class Demo { public static void main(String[] args) throws HibernateException { Student s1 = new Student("張三"); Student s2 = new Student("李四"); Course c1 = new Course("計(jì)算機(jī)"); Course c2 = new Course("英語(yǔ)"); Course c3 = new Course("航?;顒?dòng)"); Course c4 = new Course("數(shù)學(xué)"); s1.getCourses().add(c1); s1.getCourses().add(c2); s2.getCourses().add(c2); s2.getCourses().add(c3); s2.getCourses().add(c4); SessionFactory sf= new Configuration().configure().buildSessionFactory(); Session session = sf.openSession(); Transaction tx = session.beginTransaction(); session.save(s1); session.save(s2); tx.commit(); session.close(); sf.close(); } }
· 運(yùn)行這個(gè)類,數(shù)據(jù)表中生成如下數(shù)據(jù):
· 最后的項(xiàng)目結(jié)構(gòu)如下: