Hibernate關聯映射--多對一映射

單向多對一關聯關係:
這裏寫圖片描述
這裏寫圖片描述
eg:多個學生屬於一個班級。在一對多的例子上,我們進行一些改變來建立單向多對一映射:
在student類中增加一個grade班級屬性,建立其get/set方法:

    private int sid; //學生編號
    private String sname; //學生姓名
    private String sex;  //學生性別
    //在多方定義一個一方的引用->學生屬於某個班級
    private Grade grade;

修改映射文件Student.hbm.xml(注意使用many-to-one配置多對一關聯關係):

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.entity.Student" table="student">
        <id name="sid" column="sid" type="java.lang.Integer">
            <generator class="increment"></generator>
        </id>
        <property name="sname" type="java.lang.String">
            <column name="sname" length="20" not-null="true"></column>
        </property>
        <property name="sex" type="java.lang.String">
            <column name="sex"></column>
        </property>
        <!-- 配置多對一關聯關係 :many-to-one-->
        <many-to-one name="grade" class="com.entity.Grade" column="gid"></many-to-one>
    </class>  
</hibernate-mapping>

Grade.hbm.xml(因爲是單向的多對一關係,要將Grade.hbm.xml中原配置的一對多的關聯關係註釋掉):

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.entity.Grade" table="grade">
        <id name="gid" column="gid" type="java.lang.Integer">
            <generator class="increment"></generator>
        </id>
        <property name="gname" type="java.lang.String">
            <column name="gname" length="20" not-null="true"></column>
        </property>
        <property name="gdesc" type="java.lang.String">
            <column name="gdesc"></column>
        </property>     
        <!-- 配置單向的一對多關聯關係 
        <set name="students" table="student">           
            <key column="gid"></key>   指定關聯的外鍵列 
            <one-to-many class="com.entity.Student"></one-to-many>
        </set>
        -->
    </class>
</hibernate-mapping>

測試類Test02(先清空數據庫中表的數據):

package com.entity;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.util.HibernateUtil;

/**
 * 單向多對一(學生->班級)
 * */
public class Test02 {
    public static void main(String[] args) {
        save();
    }

    //保存學生信息
    public static void save(){
        Grade g=new Grade("Java","Java軟件開發一班"); //創建一個班級
        Student stu1=new Student("穆女神","女"); //創建學生
        Student stu2=new Student("小木木","男"); //創建學生

        //設置關聯關係,指定學生同班級的關係
        stu1.setGrade(g);
        stu2.setGrade(g);

        Session session=HibernateUtil.getSession();
        Transaction tx=session.beginTransaction(); //開啓事務
        //保存
        session.save(g);
        session.save(stu1);
        session.save(stu2);
        tx.commit(); //提交事務
        HibernateUtil.closeSession(session); //關閉session
    }
}

grade表:這裏寫圖片描述
student表:這裏寫圖片描述


雙向多對一關聯關係:
雙向關聯關係的建立需要在雙方配置關聯關係
注意:在本例中,student類裏面定義了grade班級屬性,已經進行了關係的維護。而inverse屬性用來指定關係的維護,其默認值爲false,表示由‘一方’(班級)來進行維護。雙方都進行了維護會使性能降低。
所以:當需要只由多方(學生)進行維護時,可將其inverse的值設置爲true,由多方維護關聯關係,一方不維護。
這裏寫圖片描述
配置一對多的關聯關係,Grade.hbm.xml(要設置inverse屬性和cascade屬性):

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.entity.Grade" table="grade">
        <id name="gid" column="gid" type="java.lang.Integer">
            <generator class="increment"></generator>
        </id>
        <property name="gname" type="java.lang.String">
            <column name="gname" length="20" not-null="true"></column>
        </property>
        <property name="gdesc" type="java.lang.String">
            <column name="gdesc"></column>
        </property>     
        <!-- 配置一對多關聯關係 ,設置inverse屬性爲true,由多方維護關聯關係,一方不維護(inverse用來指定關聯關係的維護)-->
        <!-- cascade=save-update:在保存更新班級時自動級聯操作所關聯的對象(學生)的信息 -->
        <set name="students" table="student" inverse="true" cascade="save-update">  
            <!-- 指定關聯的外鍵列  -->      
            <key column="gid"></key>   
            <one-to-many class="com.entity.Student"></one-to-many>
        </set>       
    </class>
</hibernate-mapping>

配置多對一的關聯關係,Student.hbm.xml:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.entity.Student" table="student">
        <id name="sid" column="sid" type="java.lang.Integer">
            <generator class="increment"></generator>
        </id>
        <property name="sname" type="java.lang.String">
            <column name="sname" length="20" not-null="true"></column>
        </property>
        <property name="sex" type="java.lang.String">
            <column name="sex"></column>
        </property>
        <!-- 配置多對一關聯關係 :many-to-one-->
        <many-to-one name="grade" class="com.entity.Grade" column="gid"></many-to-one>
    </class>  
</hibernate-mapping>

測試類Test02(增加一方對多方的關聯關係):

package com.entity;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.util.HibernateUtil;

//建立雙向關係
//可以由學生查找班級信息,也可由班級查找所包含的學生
public class Test02 {
    public static void main(String[] args) {
//      save();
        findGradeByStudent();
    }

    //保存學生信息
    public static void save(){
        Grade g=new Grade("Java","Java軟件開發一班"); //創建一個班級
        Student stu1=new Student("穆女神","女"); //創建學生
        Student stu2=new Student("小木木","男"); //創建學生

        //增加班級對學生的一對多的關聯關係
        //此時一方(班級)維護這種關係會產生兩條update語句,但是這兩條語句實則是多餘的,可以通過inverse屬性來去掉這兩句話
        g.getStudents().add(stu1);
        g.getStudents().add(stu2);

        //設置關聯關係,指定學生同班級的關係(多對一的關聯關係)
        stu1.setGrade(g);
        stu2.setGrade(g);

        Session session=HibernateUtil.getSession();
        Transaction tx=session.beginTransaction(); //開啓事務
        //保存
        session.save(g);//級聯操作,當保存班級時,將班級的包含的學生(這些學生當前未存儲在數據庫中)也存儲在數據庫中,而不必再手寫代碼進行學生存儲。
        //設置cascade=save-update,在保存班級時自動級聯操作所關聯的學生
//      session.save(stu1);
//      session.save(stu2);
        tx.commit(); //提交事務
        HibernateUtil.closeSession(session); //關閉session
    }

    //查詢學生所在班級信息
    public static void findGradeByStudent(){
        Session session=HibernateUtil.getSession(); //獲得session
        Student stu=(Student) session.get(Student.class, 2);//獲取id爲2的學生信息
        System.out.println(stu.getSid()+","+stu.getSname()+","+stu.getSex());

        //獲取學生所在班級信息
        Grade g=stu.getGrade();
        System.out.println(g.getGid()+","+g.getGname()+","+g.getGdesc());
        HibernateUtil.closeSession(session);

    }
}

執行save,數據庫(先要清空數據庫的表):
grade表:這裏寫圖片描述
student表:這裏寫圖片描述
執行find,控制檯:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章