在学习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); }