单向多对一关联关系:
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,控制台: