在上一个帖子我们说到了一对多的单项关联,那么我现在来说一下一对多的双向关联。单向关联就像是充分不必要条件(从左推右可以,从右推左不可以)。那么双向关联,顾名思义,就是充要条件了。
要建立双向关联,首先我们要在单向关联的基础上,在“不必要”的那一端(在这里是多的一方),多加一个“充分条件”(在这里是一的那一端)的属性。
此时student类修改成这样:
public class Student implements Serializable {
private Long sid;
private String sname;
private String sdescription;
//“一”的那一端的属性
private Classes classes;
//这里省略getter&setter
}
然后student的映射文件要修改成这样:
<class name="cn.ansel.domain.Student">
<id name="sid" length="11">
<generator class="increment"></generator>
</id>
<property name="sname" length="11"></property>
<property name="sdescription" length="111"></property>
<!--
name:表示引用名称
class:表示一的那一端的类全名
cascade:表示当hibernate保存当前类的时候,对关联的类的操作
column:表示外键;在这里可能有些人会有些疑问,我们之前在单向关联的时候,Classes.hbm.xml里面的set标签的key属性不就是外键吗?为什么在这里又要加一个外键?这也不冲突么?
这样是不冲突的,因为我们在客户端建立关系的时候(比如说classes.setStudents().addStudent(student);)hibernate是看哪个类在操作,然后就去找相应的配置文件。
-->
<many-to-one name="classes" class="cn.ansel.domain.Classes" cascade="save-update" column="cid"></many-to-one>
</class>
然后我们用例子来说明吧。
要求:通过保存一个学生来保存班级:
public void testSaveStudent_cascade_saveClasses(){
Session session=sessionFactory.openSession();
Transaction transaction=session.beginTransaction();
Classes classes=new Classes();
classes.setCdescription("not so bad");
classes.setCname("think in java");
Student student=new Student();
student.setSdescription("hark working");
student.setSname("ansel");
//建立关系
student.setClasses(classes);
session.save(student);
transaction.commit();
session.close();
}
运行结果:
输出的sql语句:
Hibernate: select max(sid) from Student
Hibernate: select max(cid) from Classes
Hibernate: insert into Classes (cname, cdescription, cid) values (?, ?, ?)
Hibernate: insert into Student (sname, sdescription, cid, sid) values (?, ?, ?, ?)
数据库中classes表和student表:
我们可以看到,在数据库中,student的外键cid是有值的,再看hibernate发出的sql语句,没有了更新外键的update语句,在昨天我们进行单向关联的关系操作的时候,都是通过保存classes来级联保存student,所以hibernate要发出维护外键的update语句,因为外键在student表里面,而在双向操作的时候,我们可以通过直接操作student表,就像上面的例子一样,hibernate是默认帮我们维护了外键的。所以我们在一对多的关系操作的时候,操作多的那一方的效率会比较高,因为少了维护外键的sql语句。
注意:在一对多的删除操作中,如果要删除某一个记录,记得先要把它们之间的关系撤销!