前面两节我们讲到了一对一的关系,一对多,多对一的关系,相对来说,是比较简单的,但有时,我们也会遇到多对多的关系,比如说:角色与权限的关系,就是典型的多对多的关系,因此,我有必要对这种关系详解,以便大家一起学习。下面来看例子:

首先我们必须建立二者的vo:

  1. public class Role implements Serializable {//这是role对象
  2. private Integer rid;
  3. private String rdesc;
  4. private String rname;
  5.  
  6. private Set<Function> funs = new HashSet<Function>();
  7. ....get,set方法已省略
  8. //这里重新写hashcode()与equals()是因为在set集合中不允许有重复的对象,也防止在添加时会重复添加相同的数据
  9. @Override
  10. public int hashCode() {
  11. final int prime = 31;
  12. int result = 1;
  13. result = prime * result + ((rdesc == null) ? 0 : rdesc.hashCode());
  14. result = prime * result + ((rname == null) ? 0 : rname.hashCode());
  15. return result;
  16. }
  17.  
  18. @Override
  19. public boolean equals(Object obj) {
  20. if (this == obj)
  21. return true;
  22. if (obj == null)
  23. return false;
  24. if (getClass() != obj.getClass())
  25. return false;
  26. Role other = (Role) obj;
  27. if (rdesc == null) {
  28. if (other.rdesc != null)
  29. return false;
  30. } else if (!rdesc.equals(other.rdesc))
  31. return false;
  32. if (rname == null) {
  33. if (other.rname != null)
  34. return false;
  35. } else if (!rname.equals(other.rname))
  36. return false;
  37. return true;
  38. }
  39. }
  1. public class Function implements Serializable {//function的vo,也就是权限
  2.  
  3. private Integer fid;
  4. private String fname;
  5. private String fdesc;
  6.  
  7. private Set<Role> roles = new HashSet<Role>();
  8.  
  9. //get,set方法已省略,对hashcode等方法如上同
  10. }

下面我们配置各自的mapping文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="com.ysq.vo" >
  6. <class name="Role" table="y_role">
  7. <id name="rid">
  8. <generator class="sequence">
  9. <param name="sequence">dept_seq</param>
  10. </generator>
  11. </id>
  12.  
  13. <property name="rname" length="20"></property>
  14. <property name="rdesc" length="20"></property>
  15.  
  16. <!-- *****cascade="save-update":如果设置成all,删除的时候,会把另外中的数据删除了
  17. --><!-- role对中间表可以设为一对多情况 table是多对多中的中间表名 -->
  18. <set name="funs" table="y_role_fun" fetch="join" cascade="save-update" lazy="false">
  19. <key column="rid"></key><!-- 当前这个类所对应的表的中间表的外键字段 -->
  20. <many-to-many class="Function" column="fid"></many-to-many>
  21. </set>
  22. </class>
  23. </hibernate-mapping>
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="com.ysq.vo" >
  6. <class name="Function" table="y_fun">
  7. <id name="fid">
  8. <generator class="sequence">
  9. <param name="sequence">dept_seq</param>
  10. </generator>
  11. </id>
  12. <property name="fname" length="20"/>
  13. <property name="fdesc" length="20"/>
  14. <!-- 权限表对中间表相当于一对多的情况 使用控制反转 使对中间表的权限交给role表来控制-->
  15. <set name="roles" table="y_role_fun" inverse="true">
  16. <key column="fid"></key><!-- y_fun在中间表所对应的外键 -->
  17. <many-to-many class="Role" column="rid"></many-to-many>
  18. </set>
  19. </class>
  20. </hibernate-mapping>

编写测试类:

  1. public class many_to_many_Test {
  2.  
  3. /**
  4. * 如果不需要控制反转的话,不能设置双向关联,不然会在中间表中添加重复字段
  5. */
  6. @Test
  7. public void addRole(){
  8. Role role = new Role();
  9. Function fun = new Function();
  10. Function fun1 = new Function();
  11. Function fun2 = new Function();
  12.  
  13. role.setRname("经理");
  14. role.setRdesc("公司上下");
  15.  
  16. fun.setFname("用户添加");
  17. fun.setFdesc("用户添加");
  18. fun1.setFname("用户删除");
  19. fun1.setFdesc("用户删除");
  20. fun2.setFname("用户修改");
  21. fun2.setFdesc("用户修改");
  22.  
  23. Session session = SessionFactoryUtils.getSession();
  24. Transaction tr = session.beginTransaction();
  25. tr.begin();
  26.  
  27. //设置单向关联
  28. /*fun.getRoles().add(role);
  29. fun1.getRoles().add(role);
  30. fun2.getRoles().add(role); *///如果设置了控制反转,可以不设置双向关联
  31.  
  32. role.getFuns().add(fun);
  33. role.getFuns().add(fun1);
  34. role.getFuns().add(fun2);
  35.  
  36. session.save(role);
  37.  
  38. tr.commit();
  39. session.close();
  40. }
  41.  
  42. /**
  43. * 删除某一角色的中的某一种权限:先查询该角色所拥有的权限,然后for遍历删除对应的权限
  44. */
  45. @Test
  46. public void deleteRole(){
  47. Session session = SessionFactoryUtils.getSession();
  48. Transaction tx = session.beginTransaction();
  49.  
  50. try {
  51. tx.begin();
  52.  
  53. Role role = (Role)session.get(Role.class, 9);
  54. Set<Function> funs = role.getFuns();
  55. /*for (Iterator iterator = funs.iterator(); iterator.hasNext();) {
  56. Function function = (Function) iterator.next();
  57. if(function.getFid() == 10){
  58. iterator.remove();
  59. break;
  60. }
  61. } */
  62. for (Function function : funs) {
  63. //删除set中对应的权限
  64. if(function.getFid() == 11){
  65. funs.remove(function);//移除set中的此权限
  66. break;//注意:这里必须要break,这与set集合中删除时游标有关
  67. }
  68. }
  69. //在重新更新此角色的权限列表
  70. role.setFuns(funs);
  71. session.update(role);
  72.  
  73. tx.commit();
  74. } catch (Exception e) {
  75. // TODO: handle exception
  76. tx.rollback();
  77. e.printStackTrace();
  78. }finally{
  79. session.close();
  80. }
  81. }
  82. /**
  83. * join fetch 【有set集合,不能用join fetch】
  84. */
  85. @Test
  86. public void findRole(){
  87. Session session = SessionFactoryUtils.getSession();
  88. List<Role> roles = session.createQuery("from Role").list();
  89. session.close();
  90.  
  91. for (Role role : roles) {
  92. System.out.println(role.getRname());
  93. if(role.getFuns().size() > 0){
  94. for (Function fun: role.getFuns()) {
  95. System.out.println(fun.getFname());
  96. }
  97. }
  98. }
  99. }
  100. }

Hibernate中的多对多关系详解(3)​的更多相关文章

  1. Hibernate中的一对多关系详解(2)

    一对多的关系:例如,部门对员工,一个部门可以有多个员工 多对一的关系:例如,员工对部门,多个员工属于一个部门,并且每个员工只能属于一个部门 那么一对多.多对一在数据库中的是怎样表示的呢?好多话都不说了 ...

  2. laravel中的多对多关系详解

    数据表之间是纵横交叉.相互关联的,laravel的一对一,一对多比较好理解,官网介绍滴很详细了,在此我就不赘述啦,重点我记下多对多的关系 一种常见的关联关系是多对多,即表A的某条记录通过中间表C与表B ...

  3. Hibernate一对多和多对一关系详解 (转载)

    :双向一对多关系,一是关系维护端(owner side),多是关系被维护端(inverse side).在关系被维护端需要通过@JoinColumn建立外键列指向关系维护端的主键列.     publ ...

  4. Qt中QGraphics类坐标映射关系详解

    1.Item(图元)坐标:属于局部坐标,通常以图元中心为原点(中心对称),非中心对称类,比如dialog类,一般以左上角为原点,正方向x朝右,y朝下. 2.setPos的坐标是父类坐标系的坐标,一般对 ...

  5. hibernate集合映射inverse和cascade详解

    hibernate集合映射inverse和cascade详解   1.到底在哪用cascade="..."? cascade属性并不是多对多关系一定要用的,有了它只是让我们在插入或 ...

  6. slf4j log4j logback关系详解和相关用法

    slf4j log4j logback关系详解和相关用法 写java也有一段时间了,一直都有用slf4j log4j输出日志的习惯.但是始终都是抱着"拿来主义"的态度,复制粘贴下配 ...

  7. 【转】UML类图与类的关系详解

    UML类图与类的关系详解   2011-04-21 来源:网络   在画类图的时候,理清类和类之间的关系是重点.类的关系有泛化(Generalization).实现(Realization).依赖(D ...

  8. C#中的Linq to Xml详解

    这篇文章主要介绍了C#中的Linq to Xml详解,本文给出转换步骤以及大量实例,讲解了生成xml.查询并修改xml.监听xml事件.处理xml流等内容,需要的朋友可以参考下 一.生成Xml 为了能 ...

  9. UML类图与类的关系详解

    摘自:http://www.uml.org.cn/oobject/201104212.asp UML类图与类的关系详解 2011-04-21 来源:网络 在画类图的时候,理清类和类之间的关系是重点.类 ...

随机推荐

  1. NVMe 图解

    http://www.ssdfans.com/?p=1143#rd&sukey=3997c0719f151520989740bb972a716fdb2dbab623808d16acd5075b ...

  2. mysql其他函数

    mysql,,); +---------------+ ,,) | +---------------+ | +---------------+ row in set (0.22 sec) mysql) ...

  3. Nginx vs Apache--reference

    May 14th, 2014 - By Walker Rowe https://anturis.com/blog/nginx-vs-apache/ What is the Nginx web and ...

  4. C# 引用SHDocVw 实现模拟网页操作

    因为最近项目需要,所以接触到了网页爬取. 1. HttpWebRequest 初期接触的都是一些比较简单的网页,通过Fiddler抓包分析后,就能模拟进行http请求,进行想要的操作. 2. WebB ...

  5. PHP 发邮件不换行

    Content-Type:用于定义用户的浏览器或相关设备如何显示将要加载的数据,或者如何处理将要加载的数据 MIME:MIME类型就是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件 ...

  6. Java SE (1)之 JFrame 组件 BorderLayout 布局

    JAVA 初期,练习SE ,桌面程序, package com.sunzhiyan; import java.awt.*; import java.awt.event.*; import javax. ...

  7. java中时间差计算

    public class Utill { public String TimeString(Date currentTime, Date beginTime){ /*默认为毫秒,除以1000是为了转换 ...

  8. Sql解锁 数据库死锁检测

    USE [DataBaseName]GO/****** Object:  StoredProcedure [dbo].[sp_check_deadlock]    Script Date: 07/04 ...

  9. SQL Server 2008文件与文件组的关系

    此文章主要向大家讲述的是SQL Server 2008文件与文件组,其中包括文件和文件组的含义与关系,文件.文件组在实践应用中经常出现的问题,查询文件组和文件语句与MSDN官方解释等相关内容的介绍. ...

  10. Linux Shell编程学习笔记——目录(附笔记资源下载)

    LinuxShell编程学习笔记目录附笔记资源下载 目录(?)[-] 写在前面 第一部分 Shell基础编程 第二部分 Linux Shell高级编程技巧 资源下载 写在前面 最近花了些时间学习She ...