在昨天的基础上我们又曾强了对一对多的学习,昨天我们只进行了一对多的 单向关系的学习,今天我们来进行一对多的双向关系的学习,我们举得例子还是一对多的例子
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="day2">
<class name="Dept" table="t_dept">
<id name="id" column="t_id" type="java.lang.Integer">
<generator class="increment">
</generator>
</id>
<property name="dname" column="t_dname" type="java.lang.String"></property>
<property name="dno" column="t_dno" type="java.lang.String"></property>
<set name="employees" inverse="true" cascade="save-update">
<key column="d_id"/>
<one-to-many class="Employee"/>
</set>
//以上的这个set标签,可能昨天没有怎么解释清楚,今天我们在重新解释一下。我觉得还是举个例子来说明是最好的
比如说我们要保存一个Dept对象,那么hibernate读取到这边的时候,他就会去Dept对象所对应的class标签,那么他就会来到
这个类,普通属性大家都好理解的把,当读到set标签的时候一看是关系属性标签,名字叫employees,cascade=save-update的时候
他就会知道这个原来是Employee对象,那么他就会session.sava(Employee)对象了,那么他就回去读取Employee对象所对应的class
那么当读到many to one 标签的时候,他就会根据dept关系属性的内容把外键的值插入到d_id列里面,所以当吧Employee插完后,程序再回到hibernate的时候,key标签的是hibernate又发现外键了,所以再插入的话就会报错,inverse=true这个属性就是这个功能,就是column这个标签的功能不能执行了
</class>
<class name="Employee" table="t_employee">
<id name="id" column="t_id" type="java.lang.Integer">
<generator class="increment">
</generator>
</id>
<property name="name" column="t_name" type="java.lang.String"></property>
<property name="email" column="t_email" type="java.lang.String"></property>
<property name="birthday" column="t_birthday" type="java.util.Date"></property>
<property name="salary" column="t_salary" type="java.lang.Double"></property>
<many-to-one name="dept" class="Dept" cascade="save-update" column="d_id"/>
// 当在插入完一个dept对象后,程序就会来插入Employee对象,因为这些Employee对象的dept关系属性,就是想对应的部门信息
所以,当执行这句话的时候,程序就可以在外键列d_id列里面出插入信息
</class>
</hibernate-mapping>
下面我们有学习了对象的关系中的多对多的关系
我们的举得例子就是 学生选课,一门课可以被多个学生选,一个学生也可以选多个课
当我们知道这样后,我们不能再向一张表中插入外键来解决问题,所以我们要多生成一张表,
用的就是学生表的id和课程表的id做联合主键
我们举得例子是保存一个学生选的课
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="day3">
<class name="Student" table="t_s">
<id name="id" column="t_id" type="java.lang.Integer">
<generator class="increment"></generator>
</id>
<property name="name" column="t_name" type="java.lang.String"></property>
<property name="age" column="t_age" type="java.lang.Integer"></property>
<property name="grade" column="t_grade" type="java.lang.Integer"></property>
<set inverse="true" name="courses" cascade="save-update" table="t_s_c">
<key column="s_id"/>
<many-to-many column="c_id" class="Course"></many-to-many>
</set>
//因为 在Strudent类中存在一个set的Course集合所以要用set标签,这个关系属性的名字叫courses,table属性指的是,关系表的名字当执行完set这一行,因为级联,所以他就去session.sava(Course) 每个Student对象都要去调用多个这个方法,因为一个学生可能选择多门课程,inverse=true属性告诉hibernate不需要再向t_s_c表中插入数据了,因为在Course类里面已经插入过了
</class>
<class name="Course" table="t_c">
<id name="id" column="t_id" type="java.lang.Integer">
<generator class="increment"></generator>
</id>
<property name="name" column="t_name" type="java.lang.String"></property>
<property name="score" column="t_score" type="java.lang.Integer"></property>
<set name="students" cascade="save-update" table="t_s_c">
<key column="c_id"/>
<many-to-many column="s_id" class="Student"></many-to-many>
</set>
//当学生对象传过来的时候,我们就去读取这个这个传过来的Student对象,因为没有inverse=true所以就去保存当前这个CourseID保存到t_s_c这张表的C_id中,而传过来的student的id就保存到关系表的s_id表中
</class>
</hibernate-mapping>