【Hibernate】——多对多关联映射

来源:互联网 发布:p2p平台数据分析 编辑:程序博客网 时间:2024/06/15 12:03
            在Hibernate中,比较基本的映射关系是一对一、一对多、多对多,其他映射都可以基于这三种映射,今天就来总结一下多对多映射。一般的设计中,多对多关联映射,需要一个中间表,Hibernate会自动生成中间表。在Hibernate中使用<many-to-many>标签来表示多对多的关联。多对多的关联映射中,在实体类中,跟一对多一样,也是用集合来表示的。同理,多对多关联映射也是分为单向和双向的。

单向多对多关联映射

            所谓单向关联映射,就是可以从一边能看到另一边,而从另一边不能看到这一边,例如,可以从User一端看到角色,但是从角色不能看到User。


实体对象(用户和角色)

           

            由此可以抽出第三张表

            

映射文件

User.hbm.xml

<hibernate-mapping><class name="com.bjpowernode.hibernate.User" table="t_user"><id name="id"><generator class="native"/></id><property name="name"/><set name="roles" table="t_user_role"><key column="user_id"/><many-to-many class="com.bjpowernode.hibernate.Role" column="role_id"/></set></class></hibernate-mapping>

Role.hbm.xml

<hibernate-mapping><class name="com.bjpowernode.hibernate.Role"><id name="id"><generator class="native"/></id><property name="name"/></class></hibernate-mapping>

查询,对象之间的加载

public void testLoad1(){Session session=null;try{session=HibernateUtils.getSession();session.beginTransaction();User user=(User)session.load(User.class, 2);System.out.println(user.getName());for (Iterator iter=user.getRoles().iterator();iter.hasNext();){Role role=(Role)iter.next();System.out.println(role.getName());}session.getTransaction().commit();}catch(Exception e){e.printStackTrace();session.getTransaction().rollback();}finally{HibernateUtils.closeSession(session);}}

双向多对多映射

            所谓双向关联映射,即可以从用户一端看到角色,也可以从角色一端看到用户。每个实体都拥有对方的set集合。


实体对象(用户和角色)

          

同样的,和单向多对多关联一样,可以抽出同样的第三张表。

 

映射文件

User.hbm.xml

<hibernate-mapping><class name="com.bjpowernode.hibernate.User" table="t_user"><id name="id"><generator class="native"/></id><property name="name"/><set name="roles" table="t_user_role"><key column="user_id"/><many-to-many class="com.bjpowernode.hibernate.Role" column="role_id"/></set></class></hibernate-mapping>

Role.hbm.xml

<hibernate-mapping><class name="com.bjpowernode.hibernate.Role"><id name="id"><generator class="native"/></id><property name="name"/><set name="users" table="t_user_role"><key column="role_id"/><many-to-many class="com.bjpowernode.hibernate.Role" column="user_id"/></set></class></hibernate-mapping>

查询,对象之间的加载

public void testLoad1(){Session session=null;try{session=HibernateUtils.getSession();session.beginTransaction();User user=(User)session.load(User.class, 2);System.out.println(user.getName());for (Iterator iter=user.getRoles().iterator();iter.hasNext();){Role role=(Role)iter.next();System.out.println(role.getName());}session.getTransaction().commit();}catch(Exception e){e.printStackTrace();session.getTransaction().rollback();}finally{HibernateUtils.closeSession(session);}}public void testLoad2(){Session session=null;try{session=HibernateUtils.getSession();session.beginTransaction();Role role=(Role)session.load(Role.class, 2);System.out.println(role.getName());for (Iterator iter=role.getUsers().iterator();iter.hasNext();){User user=(User)iter.next();System.out.println(user.getName());}session.getTransaction().commit();}catch(Exception e){e.printStackTrace();session.getTransaction().rollback();}finally{HibernateUtils.closeSession(session);}}

总结

            对比单向和双向关联映射,可以从查询加载的地方看出二者的不同,单向关联映射只能从循环遍历用户获得角色,但是双向关联映射既可以循环遍历用户获得角色,也可以循环遍历角色获得用户。

            需要注意的是<key>中的column对应的是当前类在中间表中对应的字段,即对方想要的外键,而<many-to-manyclass="com.bjpowernode.hibernate.Role"column="role_id"/>中的column指示的是中间表中本类想要的外键。还要注意的是inverse的值只能有一个true,因为如果双方都为true,那么双方都去维护关系,会造成中间关系表中出现重复的数据。在进行删除的时候Hibernate会删除id所对应的信息和中间关系表中对应的信息。



0 0