一.单向一对多的关联
通过在
一
方使用<set>元素标识多
的对象;
班级对象代表一, 学生对象代表多
数据结构中班级表学生表student2.gid 配置外键, 关联班级表主键grade.gid
点击查看练习代码
- 班级Grade实体类将学生属性设置为set集合
//在班级(一方)定义学生(多方)的集合
private Set<Student2> student2 = new HashSet<Student2>();
- 班级的hibernate映射文件Grade.hbm.xml的配置
<!-- 配置单向的一对多关联关系 -->
<set name="student2" table="student2" inverse="false" lazy="true">
<!-- 指定关联的外键列 -->
<key>
<column name="gid" />
</key>
<!-- 指定一对多中的Student2实体类 -->
<one-to-many class="entity.Student2" />
</set>
-
set的属性说明:
二.单向多对一的关联
- 多对一的关联和关系型数据库的外键参照关系匹配,
- 在已有表中的一个外键参照另一个表的主键(比如学生表添加外键关联班级表主键)
- 通过在多方持有一方的引用实现
public class Student2 implements Serializable {
private int sid;
private String sname;
private String sex;
// 在多方定义一个一方的引用, 该学生所属的班级
private Grade grade;
}
- 需要在"多"的一端使用<many-to-one>配置
Student2.hbm.xml配置
<!-- 配置多对一的关联关系 -->
<many-to-one name="grade" class="entity.Grade" column="gid" ></many-to-one>
- 新增班级和学生( 学生-->班级 多对一 )单向关联关系
/**
* 新增班级和学生( 学生-->班级 多对一 )单向关联关系
*/
public static void add()
{
//实例班级以及学生对象
Grade grade = new Grade("JAVA-1班", "java1班都是精英");
Student2 st1 = new Student2("张三1", "男");
Student2 st2 = new Student2("李四1", "女");
//设置多对一关联关系
st1.setGrade(grade); //学生张三1属于JAVA-1班
st2.setGrade(grade);//学生李四1属于JAVA-1班
//保存数据库
Transaction tx = session.beginTransaction();
session.save(grade);
session.save(st1);
session.save(st2);
tx.commit();
HibernateUtil.closeSession();
}
调用后会输出:
Hibernate: select max(gid) from grade
Hibernate: select max(sid) from student2
Hibernate: insert into grade (gname, gdesc, gid) values (?, ?, ?)
Hibernate: insert into student2 (sname, sex, gid, sid) values (?, ?, ?, ?)
Hibernate: insert into student2 (sname, sex, gid, sid) values (?, ?, ?, ?)
- 新增班级和学生( 班级-->学生一对多,学生-->班级多对一 )双向关联关系
/**
* 新增班级和学生( 班级-->学生一对多,学生-->班级多对一 )双向关联关系
*/
public static void add2()
{
//实例班级以及学生对象
Grade grade = new Grade("JAVA-1班", "java1班都是精英");
Student2 st1 = new Student2("张三1", "男");
Student2 st2 = new Student2("李四1", "女");
//设置关联关系一对多
grade.getStudent2().add(st1);
grade.getStudent2().add(st2);
//设置多对一关联关系
st1.setGrade(grade); //学生张三1属于JAVA-1班
st2.setGrade(grade);//学生李四1属于JAVA-1班
//保存数据库
Transaction tx = session.beginTransaction();
session.save(grade);
session.save(st1);
session.save(st2);
tx.commit();
HibernateUtil.closeSession();
}
执行后输出:
Hibernate: select max(gid) from grade
Hibernate: select max(sid) from student2
Hibernate: insert into grade (gname, gdesc, gid) values (?, ?, ?)
Hibernate: insert into student2 (sname, sex, gid, sid) values (?, ?, ?, ?)
Hibernate: insert into student2 (sname, sex, gid, sid) values (?, ?, ?, ?)
Hibernate: update student2 set gid=? where sid=?
Hibernate: update student2 set gid=? where sid=?
以上结果多了下面的执行语句,是多余的,因为我们是双向关联关系,也就是说学生已经知道自己属于哪个班级,班级也已经知道自已拥有哪些学生
Hibernate: update student2 set gid=? where sid=?
Hibernate: update student2 set gid=? where sid=?
所以需要在一方Grade.hbm.xml中进行配置, set属性 inverse=ture, 设置后就不会出现上面多余的两行执行语句
<!-- 配置单向的一对多关联关系, inverse=ture代表由多方维护关联关系,一方不需要进行维护 -->
<set name="student2" table="student2" inverse="false" lazy="true">
- cascade级联属性在保存班级信息时,如果已经对班级设置了班级属性学生集合set,那么在执行session.save(grade)保存班级的时候,系统会自动判断数据库有无改该班级所拥有的学生,如果没有则自动insert学生;
当然保存学生信息session.save(student)时同理; - 保存一方级联关联对象配置Grade.hbm.xml
<!-- 配置单向的一对多关联关系, inverse=ture代表由多方维护关联关系,一方不需要进行维护
cascade="save-update"代表当进行保存和更新时,级联操作所关联的对象-->
<set name="student2" table="student2" inverse="true" lazy="true" cascade="save-update">
- 保存多方级联关联对象配置Student2.hbm.xml
<!-- 配置多对一的关联关系 cascade="save-update"代表当进行保存和更新时,级联操作所关联的对象 -->
<many-to-one name="grade" class="entity.Grade" column="gid" cascade="save-update"></many-to-one>
-
casecade属性说明: