Hibernate——多对一关联映射

    在学习Hibernate中,对象的之间的关系有多种,总结多对一的关系映射,对像模型中关联是有方向的,只能从箭头的开始看到箭头的指向对象。其实多对一的原理就是在"多"的一端加入外键,指向"一"的一端。通过实例去学习它的知识点。


需求

    有两个实体对象,用户对象和分组对象。他们之间的关系是多个用户在一个组中。

Hibernate——多对一关联映射_第1张图片

Group.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.syq.hibernate.Group" table="t_group">
		<id name="id">
			<generator class="uuid"/>
		</id>
		<property name="name"/>
	</class>
</hibernate-mapping>

User.hbm.xml

通过“many-to-one”标签关联到Group对象。

<?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.syq.hibernate.User" table="t_user">
		<id name="id">
			<generator class="uuid"/>
		</id>
		<property name="name"/>
		<many-to-one name="group" column="groupid"></many-to-one>
	</class>
</hibernate-mapping>


插入数据

方法一:将Group对象和User对象都进行save操作,转换他们的状态为统一的Persintent状态。在Hibernate清理缓存是找到关联对象进行提交。

try {
			session=HibernateUtils.getSession();
			session.beginTransaction();
			
			Group group=new Group();
			group.setName("syq");
			session.save(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);
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally{
			HibernateUtils.closeSession(session);
		}


方法二:只save User对象会抛出TransientObjectException异常。原因是在Hibernate清理缓存时,User处于Persistent状态,在清理缓存中hibernate在缓存中无法找到Groyp对象。而Group处于Transient状态,没有被session管理,在数据库中没有匹配的数据。此情况下提交session会抛出TransientObjectException异常。简单说:Persistent状态的对象不能引用Transient状态的对象。

    需要在“多”的对象中,也就是User对象的.hbm.xml配置文件中添加属性cascade,而 cascade 属性如何使用呢?以下是该属性的值。

all : 所有情况下均进行关联操作。
none:所有情况下均不进行关联操作。(默认值)
save-update:在执行save/update/saveOrUpdate时进行关联操作。
delete:在执行delete时进行关联操作。


try {
			session=HibernateUtils.getSession();
			session.beginTransaction();
			
			Group group=new Group();
			group.setName("syq");
			
			User user1=new User();
			user1.setName("张三");
			user1.setGroup(group);
			
			User user2=new User();
			user2.setName("李四");
			user2.setGroup(group);
			
			session.save(user1);
			session.save(user2);
			
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally{
			HibernateUtils.closeSession(session);
		}
修改User对象配置属性
<many-to-one name="group" column="groupid" cascade="save-update"></many-to-one>

查询数据

    查询数据时如果两个对象有关系,可以进行级联查询按照级联的方向,可以通过User对象查询级联的Group对象的内容。

try {
			session=HibernateUtils.getSession();
			session.beginTransaction();
			
			User user=(User)session.load(User.class, "402898394ee74fe3014ee74fe4910003");
			System.out.println("username:"+user.getName());
			System.out.println("userGroupname:"+user.getGroup().getName());
			session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally{
			HibernateUtils.closeSession(session);
		}


    总之,在多对一的单向关系映射中,插入数据时Persistent状态的对象不能引用Transient状态的对象。在查询数据时,级联查询按照级联的方向,可以通过“多”的对象查询级联的“一”的对象的内容。

你可能感兴趣的:(Hibernate)