9.hibernate映射(多對多)

多對多也是分為:

  • 單向多對多
  • 雙向多對多

案例說明:

一個學(xué)生可以上多個班級的課归粉,一個班級也可以有多個學(xué)生

先來看看實體類

classes.java班級類

    package entity;
    
    import java.util.Set;
    
    /**
     * 這里還是用classes做測試,多對多,也就是一個學(xué)生可以在多個班上課,一個班可以有多個學(xué)生
     * @author arkulo
     *
     */
    public class Classes {
        private int id;
        private String className;
        private Set<Student> student;
        
        
        
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getClassName() {
            return className;
        }
        public void setClassName(String className) {
            this.className = className;
        }
        public Set<Student> getStudent() {
            return student;
        }
        public void setStudent(Set<Student> student) {
            this.student = student;
        }
    }

Student.java學(xué)生類

    package entity;
    
    public class Student {
        private int id;
        private String name;
    //  private Classes classes;
        
        
    //  public Classes getClasses() {
    //      return classes;
    //  }
    //  public void setClasses(Classes classes) {
    //      this.classes = classes;
    //  }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
    }

一谋右、單向多對多

Classes.hbm.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="entity">
        <class name="Classes" dynamic-update="true" >
            <id name="id">
                <generator class="native"/>
            </id>
            <property name="className" />
            <set name="student" table="_relation_classes_student">
            <!-- 這里維護(hù)一張中間表蜓陌,student_id關(guān)聯(lián)student表,classes_id關(guān)聯(lián)classes表 -->
                <key column="classes_id"></key>
                <many-to-many class="Student" column="student_id"></many-to-many>
            </set>
        </class>    
    </hibernate-mapping>

這里要仔細(xì)注意中間表的寫法施蜜,table確定表名稱,key標(biāo)簽的column屬性設(shè)置關(guān)聯(lián)classes主鍵雌隅,manytomany標(biāo)簽column屬性設(shè)置關(guān)聯(lián)student表主鍵》現(xiàn)在對象之間的關(guān)聯(lián)關(guān)系,是由classes維護(hù)的恰起,student這邊么有維護(hù)關(guān)系修械,請看下面的student的映射文件

student.hbm.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="entity">
        <class name="Student" dynamic-update="true">
            <id name="id">
                <generator class="native"/>
            </id>
            <property name="name" />
        </class>    
    </hibernate-mapping>

單元測試:
package entity;

    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    import org.hibernate.classic.Session;
    
    import junit.framework.TestCase;
    import util.hibernateUtil;
    
    /**
     * 單向多對多關(guān)聯(lián)
     * 測試目的:
     * 1. 測試添加
     * 2. 測試查詢
     * 3. 測試刪除
     * 
     * @author arkulo
     *
     */
    
    public class testManyToMany extends TestCase {
    //  新增,單向检盼,是在classes端維護(hù)的關(guān)系
        public void test1() {
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
    //          先插入3條學(xué)生記錄肯污,然后插入班級記錄,又插入三條關(guān)系表記錄
                
                Student st1 = new Student();
                st1.setName("張三");
                Student st2 = new Student();
                st2.setName("李四");          
                Student st3 = new Student();
                st3.setName("王五");  
                session.save(st1);
                session.save(st2);
                session.save(st3);
                
                Set<Student> jihe = new HashSet();
                jihe.add(st1);
                jihe.add(st2);
                jihe.add(st3);
                
                Classes cl = new Classes();
                cl.setClassName("一年級三班");
                cl.setStudent(jihe);
                            
                session.save(cl);
    
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }
        }
        
        
    //  查詢某個班的學(xué)生情況
        public void test2()
        {
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction(); 
    //          這里先發(fā)出一個查詢班級的sql語句吨枉,并打印蹦渣。當(dāng)需要用到與班級關(guān)聯(lián)的學(xué)生的時候,
    //          系統(tǒng)又發(fā)出了一條sql語句貌亭,將所有班級學(xué)生一起查出來
                Classes cl = (Classes)session.get(Classes.class, 1);
                System.out.println("班級名稱:"+cl.getClassName());
                Iterator<Student> it = cl.getStudent().iterator();
                while(it.hasNext())
                {
                    Student student = it.next();
                    System.out.println("學(xué)生姓名:"+student.getName());
                }
                
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }       
        }
        
        
    //  刪除班級是否會拋出異常柬唯?還是會一起刪除學(xué)生
        public void test3()
        {
            test1();
            System.out.println("------------------------------------------");
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction(); 
    //          這里先發(fā)出一個查詢班級的sql語句,并打印圃庭。當(dāng)需要用到與班級關(guān)聯(lián)的學(xué)生的時候锄奢,
    //          系統(tǒng)又發(fā)出了一條sql語句,將所有班級學(xué)生一起查出來
                Classes cl = (Classes)session.get(Classes.class, 1);
                System.out.println("班級名稱:"+cl.getClassName());
                Iterator<Student> it = cl.getStudent().iterator();
                while(it.hasNext())
                {
                    Student student = it.next();
                    System.out.println("學(xué)生姓名:"+student.getName());
                }
                
    //          這個時候緩存中已經(jīng)存在班級和所有相關(guān)學(xué)生的對象緩存剧腻,這時候我們刪除班級斟薇,看是否能一起刪除學(xué)生數(shù)據(jù)
    //          實際上,這個操作的sql語句如下:
    //          Hibernate: delete from _relation_classes_student where classes_id=?
    //          Hibernate: delete from Classes where id=?
    //          先刪除了關(guān)系表中的所有該班級的數(shù)據(jù)恕酸,然后刪除了班級表中的數(shù)據(jù)記錄
                session.delete(cl);
                
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }       
        }   
    }

二堪滨、雙向多對多

student.hbm.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="entity">
        <class name="Student" dynamic-update="true">
            <id name="id">
                <generator class="native"/>
            </id>
            <property name="name" />
            <set name="classes">
                <key column="student_id"></key>
                <many-to-many class="Classes" column="classes_id"></many-to-many>
            </set>
        </class>    
    </hibernate-mapping>

單元測試:

    package entity;
    
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    import org.hibernate.classic.Session;
    
    import junit.framework.TestCase;
    import util.hibernateUtil;
    
    /**
     * 雙向多對多關(guān)聯(lián)
     * 測試目的:
     * 一個課程班級對應(yīng)多個學(xué)生,一個學(xué)生也可以報多個課程班級
     * 1. 測試添加
     * 2. 測試查詢
     * 3. 測試刪除
     * 
     * @author arkulo
     *
     */
    
    public class testManyToMany extends TestCase {
    //  新增蕊温,雙向袱箱,是在classes端維護(hù)的關(guān)系
        public void test1() {
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
    //          先插入3條學(xué)生記錄,然后插入班級記錄义矛,又插入三條關(guān)系表記錄
                
                Student st1 = new Student();
                st1.setName("張三");
                Student st2 = new Student();
                st2.setName("李四");          
                Student st3 = new Student();
                st3.setName("王五");  
                session.save(st1);
                session.save(st2);
                session.save(st3);
    
                Classes cl = new Classes();
                cl.setClassName("音樂班");
                Classes cl1 = new Classes();
                cl1.setClassName("美術(shù)班");
                Classes cl2 = new Classes();
                cl2.setClassName("跆拳道班");       
                
    //          上音樂班的學(xué)生
                Set<Student> jihe = new HashSet();
                jihe.add(st1);
                jihe.add(st2);
                cl.setStudent(jihe);
    //          上美術(shù)班的同學(xué)
                Set<Student> jihe1 = new HashSet();
                jihe1.add(st2);
                jihe1.add(st3);
                cl1.setStudent(jihe1);          
    //          上跆拳道班的學(xué)生
                Set<Student> jihe2 = new HashSet();
                jihe2.add(st1);
                jihe2.add(st3);
                cl2.setStudent(jihe2);                  
    
                            
                session.save(cl);
                session.save(cl1);
                session.save(cl2);
    
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }
        }
        
        
    //  查詢某個班的學(xué)生情況
        public void test2()
        {
            test1();
            System.out.println("------------------------------");
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction(); 
    //          這里先發(fā)出一個查詢班級的sql語句发笔,并打印。當(dāng)需要用到與班級關(guān)聯(lián)的學(xué)生的時候凉翻,
    //          系統(tǒng)又發(fā)出了一條sql語句了讨,將所有班級學(xué)生一起查出來
                Classes cl = (Classes)session.get(Classes.class, 1);
                System.out.println("班級名稱:"+cl.getClassName());
                Iterator<Student> it = cl.getStudent().iterator();
                while(it.hasNext())
                {
                    Student student = it.next();
                    System.out.println("學(xué)生姓名:"+student.getName());
                }
                
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }       
        }
        
        
    //  刪除班級是否會拋出異常?還是會一起刪除學(xué)生
        public void test3()
        {
            test1();
            System.out.println("------------------------------------------");
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction(); 
    //          這里先發(fā)出一個查詢班級的sql語句,并打印前计。當(dāng)需要用到與班級關(guān)聯(lián)的學(xué)生的時候胞谭,
    //          系統(tǒng)又發(fā)出了一條sql語句,將所有班級學(xué)生一起查出來
                Classes cl = (Classes)session.get(Classes.class, 1);
                System.out.println("班級名稱:"+cl.getClassName());
                Iterator<Student> it = cl.getStudent().iterator();
                while(it.hasNext())
                {
                    Student student = it.next();
                    System.out.println("學(xué)生姓名:"+student.getName());
                }
                
    //          這個時候緩存中已經(jīng)存在班級和所有相關(guān)學(xué)生的對象緩存男杈,這時候我們刪除班級丈屹,看是否能一起刪除學(xué)生數(shù)據(jù)
    //          實際上,這個操作的sql語句如下:
    //          Hibernate: delete from _relation_classes_student where classes_id=?
    //          Hibernate: delete from Classes where id=?
    //          先刪除了關(guān)系表中的所有該班級的數(shù)據(jù)伶棒,然后刪除了班級表中的數(shù)據(jù)記錄
                session.delete(cl);
                
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }       
        }   
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末旺垒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子肤无,更是在濱河造成了極大的恐慌先蒋,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宛渐,死亡現(xiàn)場離奇詭異竞漾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)皇忿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門畴蹭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鳍烁,你說我怎么就攤上這事叨襟。” “怎么了幔荒?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵糊闽,是天一觀的道長。 經(jīng)常有香客問我爹梁,道長右犹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任姚垃,我火速辦了婚禮念链,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘积糯。我一直安慰自己掂墓,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布看成。 她就那樣靜靜地躺著君编,像睡著了一般。 火紅的嫁衣襯著肌膚如雪川慌。 梳的紋絲不亂的頭發(fā)上吃嘿,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天祠乃,我揣著相機(jī)與錄音,去河邊找鬼兑燥。 笑死亮瓷,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的贪嫂。 我是一名探鬼主播寺庄,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼艾蓝,長吁一口氣:“原來是場噩夢啊……” “哼力崇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起赢织,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤亮靴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后于置,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體茧吊,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年八毯,在試婚紗的時候發(fā)現(xiàn)自己被綠了搓侄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡话速,死狀恐怖讶踪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情泊交,我是刑警寧澤乳讥,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站廓俭,受9級特大地震影響云石,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜研乒,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一汹忠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧雹熬,春花似錦宽菜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至仰楚,卻和暖如春隆判,著一層夾襖步出監(jiān)牢的瞬間犬庇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工侨嘀, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留臭挽,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓咬腕,卻偏偏與公主長得像欢峰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子涨共,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 再開始本次知識點之前纽帖,我們先來思考下get與load的區(qū)別。 對于Hibernate get方法举反,Hibernat...
    FTOLsXD閱讀 357評論 0 1
  • 其實和多對一本質(zhì)上是一樣的懊直,也是在many的一方加一個字段作為外鍵,指向one的一方的主鍵火鼻,只是加載的時候不一樣室囊。...
    yjaal閱讀 303評論 0 1
  • hibernate表關(guān)聯(lián)的各種配置: 1、多對多單向: user----->role user.hbm.xml: ...
    加油小杜閱讀 283評論 0 0
  • 作為一種輕量級的關(guān)系映射工具魁索,Hibernate支持各種關(guān)系映射融撞,例如:多對一、一對多和一對一的數(shù)據(jù)庫表關(guān)系粗蔚,通過...
    Ystrator閱讀 532評論 0 1
  • 文/葉老巫 (5/160尝偎,每天更文3000,連續(xù)160天) 本文關(guān)鍵詞:套路支鸡、夢想冬念、阻礙、意外 1牧挣、 故事怎樣寫急前?...
    葉兩步閱讀 1,256評論 0 31