在学习Hibernate中,对象的之间的关系有多种,总结多对一的关系映射,对像模型中关联是有方向的,只能从箭头的开始看到箭头的指向对象。其实多对一的原理就是在"多"的一端加入外键,指向"一"的一端。通过实例去学习它的知识点。
需求
有两个实体对象,用户对象和分组对象。他们之间的关系是多个用户在一个组中。
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);
}