【Many-to-one】
多对一关联映射是最常见的单向关联关系,多对一能够实现查“多”的一方的时候,也出现“一”的那一方。对象图形中,关联是有方向的,只能通过用户可以找到相应的组。关联图形中,因为加上了外键,所以可以从用户看到组,也可以从组看到用户。在多的一端加外键,指向一的一端。多对一的关系就体现在设置了外键。
在User一端写<many-to-one>标签,设置了外键,使用了级联属性以保持和更新的时候执行级联操作。
User.hbm.xml 代码:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >
<class name="com.bjpowernode.hibernate.User" table="t_user">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- 多对一标签,设置外键,使用级联属性--!>
<many-to-one name="group" column="groupid" cascade="save-update"/>
</class>
</hibernate-mapping>
Many2OneTest 代码:
public void testSave1(){
Session session=null;
try{
session=HibernateUtils.getSession();
session.beginTransaction();
Group group=new Group();
group.setName("小组");
session.save(group);//纳入session管理,group 就为持久状态,就可以保存数据了
User user1 = new User();
user1.setName("琪娅拉");
user1.setGroup(group);
User user2=new User();
user2.setName("高孚");
user2.setGroup(group);
session.save(user1);
session.save(user2);
//可以正确的保存数据
//因为Group和User都是Persistent状态的对象
//所以在hibernate清理缓存时在session中可以找到关联对象
session.getTransaction().commit();
}catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}finally{
HibernateUtils.closeSession(session);
}
}
如果上面代码中不写 session.save(group); ,在hibernate清理缓存的时候就会抛出 TransientObjectException的错误。因为未保存的group是transient状态,在数据库中没有匹配的数据。而user是persistent状态,在清理缓存时hibernate在缓存中无法找到group对象,也就是persistent状态的对象不能引用transient状态的对象。【级联属性 cascade】
在多对一关系中比较常用的属性,比如很多商品同属于同一类。级联是指两个对象之间的操作联动关系,对一个对象执行了操作之后,对其指定的级联对象也需要执行相同的操作。级联是对象之间的连锁操作。级联影响的增加、删除 和修改,并不影响查询。影响增加、删除、 修改的意思,就是数据变动会级联变动,但不影响查询。我们需要在“多”的一端映射文件中设置级联属性。
cascade取值的4种情况:
all:代表在所有的情况下都执行级联操作
none:在所有情况都不执行级联操作
save-update:在保持和更新的时候执行级联操作。
delete:在删除的时候执行级联操作。常用情况删除组的时候同时删除了组内成员。