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,控制台:
这里写图片描述

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