您所在的位置:主页 > Java培训 >

映射单向多对一单向关联关系,单向多对一使用方法

时间:2014-04-21 09:28来源:未知 作者:疯狂java 点击:

映射单向多对一关联

        单向多对一是最常见的单向关联关系。单向一对一关联又可以分为基于外键单向一对一关联和基于主键单向一对一关联。其中,基于外键的单词一对一关联和单向多对一关联几乎相同,唯一不同就是单向一对一关联中的外键字段具有唯一性约束。在下面代码中,实例化并且封装了一个Student对象st。然后又实例化并且封装了两个Score对象,分别为sc、sc2,它们都以Student对象st作为参数而进行了封装,也即两个Score对象关联了同一个Student对象。因为在映射文件Score.hbm.xml中指定了级联操作为save-update,有因为是单向多对一,所以由多方Score对象来维护一方的Student关联对象。所以在保存两个Score对象的同时,Student对象st也将被保存。

单向多对一使用方法

Student st=new Student();//创建一个Student对象
st.setName("huizhi");
st.setNumber("2708");
st.setClassid(200);
Score sc=new Score();//创建一个Score对象
sc.setScore(96);
sc.setType("M");
sc.setStudent(st);//关联Student对象
Score sc2=new Score();//创建一个Score对象
sc2.setScore(90);
sc2.setType("N");
sc2.setStudent(st);//关联Student对象
saveObject(sc);//保存对象sc
saveObject(sc2);//保存对象sc2

          在多对一映射中,not-null属性用来指定外键不能为空,外键的属性可以直接在<many-to-ont>元素中指定,也可以通过其子元素<column>来指定。因为外键参照student表中的主键,所以在保存Score对象时,一定要级联刀其所关联的Student对象。因为Hibernate在持久化一个临时对象是,在默认情况下,不会自动持久化所关联的其他临时对象。在映射Score.hbm.xml中,去掉设置级联的属性 cascade。此时重新执行保存其他两个Score对象的代码,将出现异常。
        hibernate在保存Score对象是,并不自动保存Student对象,所以这就导致在保存Score对象时,它所引用的外键为空,导致报出异常。所以可以通过设定cascade属性来解决这个问题,同时保存Student对象。cascade属性的取值有以下几种。none:在保存、更新或删除对象时,忽略其他关联的对象。他是cascade属性的默认值。save-update:当通过Session的save()、update()以及saveOrUpdate()方法保存或更新当前对象是,级联保存所有关联的新建的临时对象,并且级联更新所有关联的游历对象。delete:当通过Session的delete()方法删除当前的对象是,级联删除所有关联的对象。all:包含save-update以及delete的行为。此外,对当前对象执行evict()或lock()操作时,也会对所有关联的持久话对象执行evict() 或 lock()操作。delete-orphan:删除所有和当前对象解除关联关系的对象。all-delete-orphan:包含all 和 delete-ophan。

       如果不想同时保存Student对象,可以去掉not-null属性,或者设定其值为false,但是如果在数据库设置外键不能为空,此时仍不能保存Score对象。将not-null设置为true,还是设置为false,由实际情况决定。假如,如果允许外键为空,保存的成绩将不会知道属于哪个学生,失去了实际的价值,所以在以上实例中应该设定为true。
与单向的多对一关联相反,从Student刀Score是单向的一对多关联,在单向的一对多关联中,关联关系的两端有一端来维护多端,因此在更新或者删除一端对象时,会级联更新N个多端得对象,显然会严重影响性能。假如,如果更新1个Student对象,则hibernate会发送3条SQL语句来更新3个Score对象,允许发送1条SQL语句就够了,但hibernate并不知道应该那样做。因此单向一对多关联也很少使用,也不推荐使用,这时大家可能会想到使用单向多对一的关联,可以有多端来维护关联关系,以上问题就不存在了,事实上就是这样。