8.hibernate映射(一對(duì)多)

一對(duì)多也是分為兩種:

  • 單向一對(duì)多
  • 雙向一對(duì)多

先來看一下公用的實(shí)體類

classes實(shí)體類

    package entity;
    
    import java.util.Set;
    
    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實(shí)體類(單向的時(shí)候沒有class這個(gè)屬性)

    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;
        }
    }

單向一對(duì)多

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" cascade="delete">
                <!-- 這里的column是指數(shù)據(jù)庫中student表中會(huì)添加外鍵classid,關(guān)聯(lián)classes表的主鍵 -->
                <key column="classid"></key>
                <one-to-many class="Student" />
            </set>
        </class>    
    </hibernate-mapping>

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.ArrayList;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    import org.hibernate.classic.Session;
    
    import junit.framework.TestCase;
    import util.hibernateUtil;
    
    /**
     * 單向一對(duì)多(項(xiàng)目名稱寫錯(cuò)了邑时,應(yīng)該是一對(duì)多)
     * 測試目的:
     * 1. 新增數(shù)據(jù)拜隧,是否會(huì)級(jí)聯(lián)保存下面?什么時(shí)候發(fā)出sql語句蚪战?
     * 2. 查詢數(shù)據(jù),會(huì)不會(huì)級(jí)聯(lián)查詢庸推?
     * 3. 刪除數(shù)據(jù)蒜茴,會(huì)不會(huì)級(jí)聯(lián)刪除?
     * @author arkulo
     *
     */
    
    public class testManytoone extends TestCase {
        // 新增數(shù)據(jù)
        public void test1() {
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
    
                Student st1 = new Student();
                st1.setName("張三");
                Student st2 = new Student();
                st2.setName("李四");
                Student st3 = new Student();
                st3.setName("王五");
    
                // 這里必須先保存三個(gè)student疆栏,否則它們沒有ID曾掂,最后會(huì)拋異常
                // 這是sql執(zhí)行的順序
                // Hibernate: insert into Student (name) values (?)
                // Hibernate: insert into Student (name) values (?)
                // Hibernate: insert into Student (name) values (?)
                // Hibernate: insert into Classes (className) values (?)
                // Hibernate: update Student set classid=? where id=?
                // Hibernate: update Student set classid=? where id=?
                // Hibernate: update Student set classid=? where id=?
    
                session.save(st1);
                session.save(st2);
                session.save(st3);
    
    //          這屬于在one的一方維護(hù)關(guān)系
                Set<Student> set = new HashSet<Student>();
                set.add(st1);
                set.add(st2);
                set.add(st3);
    
                Classes cl = new Classes();
                cl.setClassName("一年級(jí)三班");
                cl.setStudent(set);
    
                session.save(cl);
    
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }
        }
    
        // 查詢數(shù)據(jù)
        public void test2() {
            test1();
            System.out.println("-------------------------------------------------");
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
    
                // 發(fā)出兩條sql語句
                // 如果沒有緩存的情況下,這里的iterate會(huì)產(chǎn)生n+1問題
                Iterator st = session.createQuery("from Classes").iterate();
                while (st.hasNext()) {
                    Classes cl = (Classes) st.next();
                    System.out.println("班級(jí):" + cl.getClassName());
                    Set<Student> students = cl.getStudent();
                    Iterator<Student> it = students.iterator();
                    while (it.hasNext()) {
                        Student s = it.next();
                        System.out.println("用戶名:" + s.getName());
                    }
                }
    
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }
        }
    
        // 刪除數(shù)據(jù)
        public void test3() {
            test1();
            System.out.println("-------------------------------------------------");
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
    
                // 再不設(shè)置級(jí)聯(lián)的情況下壁顶,刪除classes珠洗,是否會(huì)刪除student的記錄
                Classes cl = (Classes) session.get(Classes.class, 1);
                System.out.println("班級(jí)名稱:" + cl.getClassName());
                Set<Student> students = cl.getStudent();
                Iterator<Student> it = students.iterator();
                while (it.hasNext()) {
                    Student s = it.next();
                    System.out.println("學(xué)生姓名:" + s.getName());
                }
    
                System.out.println("------------------------------------------");
                // 不設(shè)置級(jí)聯(lián)關(guān)系為delete的情況下,刪除classes若专,會(huì)自動(dòng)的把student表中的classid字段設(shè)置為null
                // 設(shè)置級(jí)聯(lián)關(guān)系為delete后许蓖,sql語句順序?yàn)橄拢?                // Hibernate: update Student set classid=null where classid=?
                // Hibernate: delete from Student where id=?
                // Hibernate: delete from Student where id=?
                // Hibernate: delete from Student where id=?
                // Hibernate: delete from Classes where id=?
                // 可以看出,即使設(shè)置了級(jí)聯(lián)為delete调衰,也會(huì)先更新classid字段為null膊爪,然后在刪除student,最后刪除classes
                session.delete(cl);
    
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }
        }
    
    }

雙向一對(duì)多

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" cascade="delete" inverse="true">
                <!-- 這里的column是指數(shù)據(jù)庫中student表中會(huì)添加外鍵classid嚎莉,關(guān)聯(lián)classes表的主鍵 -->
                <key column="classid"></key>
                <one-to-many class="Student" />
            </set>
        </class>    
    </hibernate-mapping>

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" />
            <many-to-one name="classes" column="classid"></many-to-one>
        </class>    
    </hibernate-mapping>

單元測試:

    package entity;
    
    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    import org.hibernate.classic.Session;
    
    import junit.framework.TestCase;
    import util.hibernateUtil;
    
    /**
     * 雙向一對(duì)多(一般情況下米酬,不推薦在one的一方維護(hù)關(guān)系)
     * 
     * 測試目的
     * 0. 使many方的設(shè)置失效,由one方維護(hù)關(guān)系
     * 1. 新增數(shù)據(jù)趋箩,是否會(huì)級(jí)聯(lián)保存赃额?什么時(shí)候發(fā)出sql語句加派?
     * 2. 查詢數(shù)據(jù),會(huì)不會(huì)級(jí)聯(lián)查詢跳芳?
     * 3. 刪除數(shù)據(jù)芍锦,會(huì)不會(huì)級(jí)聯(lián)刪除?
     * @author arkulo
     *
     */
    
    public class testManytoone extends TestCase {
        // 新增數(shù)據(jù)
        public void test1() {
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
                
                Classes cl = new Classes();
                cl.setClassName("一年級(jí)三班");
                session.save(cl);
    //          這是在many端維護(hù)的關(guān)系飞盆,比較簡單娄琉,起碼不用中間還需要一個(gè)set集合
                Student st1 = new Student();
                st1.setName("張三");
                st1.setClasses(cl);
    
                session.save(st1);
    
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }
        }
    
        // 查詢數(shù)據(jù)
        public void test2() {
            test1();
            System.out.println("-------------------------------------------------");
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
    
                // 發(fā)出兩條sql語句
                // 如果沒有緩存的情況下,這里的iterate會(huì)產(chǎn)生n+1問題
                Iterator st = session.createQuery("from Classes").iterate();
                while (st.hasNext()) {
                    Classes cl = (Classes) st.next();
                    System.out.println("班級(jí):" + cl.getClassName());
                    Set<Student> students = cl.getStudent();
                    Iterator<Student> it = students.iterator();
                    while (it.hasNext()) {
                        Student s = it.next();
                        System.out.println("用戶名:" + s.getName());
                    }
                }
    
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }
        }
    
        // 刪除數(shù)據(jù)
        public void test3() {
            test1();
            System.out.println("-------------------------------------------------");
            Session session = null;
    
            try {
                session = hibernateUtil.getSession();
                session.beginTransaction();
    
                // 再不設(shè)置級(jí)聯(lián)的情況下吓歇,刪除classes车胡,是否會(huì)刪除student的記錄
                Classes cl = (Classes) session.get(Classes.class, 1);
                System.out.println("班級(jí)名稱:" + cl.getClassName());
                Set<Student> students = cl.getStudent();
                Iterator<Student> it = students.iterator();
                while (it.hasNext()) {
                    Student s = it.next();
                    System.out.println("學(xué)生姓名:" + s.getName());
                }
    
                System.out.println("------------------------------------------");
                // 不設(shè)置級(jí)聯(lián)關(guān)系為delete的情況下,刪除classes照瘾,系統(tǒng)會(huì)提示外鍵關(guān)聯(lián)并拋出異常
                
    //          在student映射文件上設(shè)置級(jí)聯(lián)為delete匈棘,系統(tǒng)也會(huì)報(bào)錯(cuò),因?yàn)檫@里我們刪除的是classes
                
                // 在classes上設(shè)置級(jí)聯(lián)關(guān)系為delete后析命,sql語句順序?yàn)橄拢?    //          Hibernate: delete from Student where id=?
    //          Hibernate: delete from Classes where id=?
                // 這樣就實(shí)現(xiàn)了級(jí)聯(lián)刪除
                session.delete(cl);
    
                session.getTransaction().commit();
            } catch (Exception e) {
                e.printStackTrace();
                session.getTransaction().rollback();
            } finally {
                hibernateUtil.closeSession(session);
            }
        }
    
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末主卫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子鹃愤,更是在濱河造成了極大的恐慌簇搅,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件软吐,死亡現(xiàn)場離奇詭異瘩将,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)凹耙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門姿现,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人肖抱,你說我怎么就攤上這事备典。” “怎么了意述?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵提佣,是天一觀的道長。 經(jīng)常有香客問我荤崇,道長拌屏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任术荤,我火速辦了婚禮倚喂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘喜每。我一直安慰自己务唐,他們只是感情好雳攘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布带兜。 她就那樣靜靜地躺著枫笛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪刚照。 梳的紋絲不亂的頭發(fā)上刑巧,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天,我揣著相機(jī)與錄音无畔,去河邊找鬼啊楚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛浑彰,可吹牛的內(nèi)容都是我干的恭理。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼郭变,長吁一口氣:“原來是場噩夢啊……” “哼颜价!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起诉濒,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤周伦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后未荒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體专挪,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年片排,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寨腔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡率寡,死狀恐怖脆侮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情勇劣,我是刑警寧澤靖避,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站比默,受9級(jí)特大地震影響幻捏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜命咐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一篡九、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧醋奠,春花似錦榛臼、人聲如沸伊佃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽航揉。三九已至,卻和暖如春金刁,著一層夾襖步出監(jiān)牢的瞬間帅涂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國打工尤蛮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留媳友,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓产捞,卻偏偏與公主長得像醇锚,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子坯临,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

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

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法焊唬,類相關(guān)的語法,內(nèi)部類的語法尿扯,繼承相關(guān)的語法求晶,異常的語法,線程的語...
    子非魚_t_閱讀 31,622評(píng)論 18 399
  • 其實(shí)和多對(duì)一本質(zhì)上是一樣的衷笋,也是在many的一方加一個(gè)字段作為外鍵芳杏,指向one的一方的主鍵,只是加載的時(shí)候不一樣辟宗。...
    yjaal閱讀 301評(píng)論 0 1
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 3,810評(píng)論 0 11
  • 再開始本次知識(shí)點(diǎn)之前爵赵,我們先來思考下get與load的區(qū)別。 對(duì)于Hibernate get方法泊脐,Hibernat...
    FTOLsXD閱讀 354評(píng)論 0 1
  • 3.4 有時(shí)候空幻,原以為艱難的事情做起來竟然很簡單,其實(shí)是你給自己設(shè)了一道坎容客,把自己看的太低秕铛,把問題看的太大而已。而...
    real_x閱讀 417評(píng)論 0 0