标签:
前面两节我们讲到了一对一的关系,一对多,多对一的关系,相对来说,是比较简单的,但有时,我们也会遇到多对多的关系,比如说:角色与权限的关系,就是典型的多对多的关系,因此,我有必要对这种关系详解,以便大家一起学习。下面来看例子:
首先我们必须建立二者的vo:
public class Role implements Serializable {//这是role对象 private Integer rid; private String rdesc; private String rname; private Set<Function> funs = new HashSet<Function>(); ....get,set方法已省略 //这里重新写hashcode()与equals()是因为在set集合中不允许有重复的对象,也防止在添加时会重复添加相同的数据 @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((rdesc == null) ? 0 : rdesc.hashCode()); result = prime * result + ((rname == null) ? 0 : rname.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Role other = (Role) obj; if (rdesc == null) { if (other.rdesc != null) return false; } else if (!rdesc.equals(other.rdesc)) return false; if (rname == null) { if (other.rname != null) return false; } else if (!rname.equals(other.rname)) return false; return true; } }
public class Function implements Serializable {//function的vo,也就是权限 private Integer fid; private String fname; private String fdesc; private Set<Role> roles = new HashSet<Role>(); //get,set方法已省略,对hashcode等方法如上同 }
下面我们配置各自的mapping文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.ysq.vo" > <class name="Role" table="y_role"> <id name="rid"> <generator class="sequence"> <param name="sequence">dept_seq</param> </generator> </id> <property name="rname" length="20"></property> <property name="rdesc" length="20"></property> <!-- *****cascade="save-update":如果设置成all,删除的时候,会把另外中的数据删除了 --><!-- role对中间表可以设为一对多情况 table是多对多中的中间表名 --> <set name="funs" table="y_role_fun" fetch="join" cascade="save-update" lazy="false"> <key column="rid"></key><!-- 当前这个类所对应的表的中间表的外键字段 --> <many-to-many class="Function" column="fid"></many-to-many> </set> </class> </hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.ysq.vo" > <class name="Function" table="y_fun"> <id name="fid"> <generator class="sequence"> <param name="sequence">dept_seq</param> </generator> </id> <property name="fname" length="20"/> <property name="fdesc" length="20"/> <!-- 权限表对中间表相当于一对多的情况 使用控制反转 使对中间表的权限交给role表来控制--> <set name="roles" table="y_role_fun" inverse="true"> <key column="fid"></key><!-- y_fun在中间表所对应的外键 --> <many-to-many class="Role" column="rid"></many-to-many> </set> </class> </hibernate-mapping>
编写测试类:
public class many_to_many_Test { /** * 如果不需要控制反转的话,不能设置双向关联,不然会在中间表中添加重复字段 */ @Test public void addRole(){ Role role = new Role(); Function fun = new Function(); Function fun1 = new Function(); Function fun2 = new Function(); role.setRname("经理"); role.setRdesc("公司上下"); fun.setFname("用户添加"); fun.setFdesc("用户添加"); fun1.setFname("用户删除"); fun1.setFdesc("用户删除"); fun2.setFname("用户修改"); fun2.setFdesc("用户修改"); Session session = SessionFactoryUtils.getSession(); Transaction tr = session.beginTransaction(); tr.begin(); //设置单向关联 /*fun.getRoles().add(role); fun1.getRoles().add(role); fun2.getRoles().add(role); *///如果设置了控制反转,可以不设置双向关联 role.getFuns().add(fun); role.getFuns().add(fun1); role.getFuns().add(fun2); session.save(role); tr.commit(); session.close(); } /** * 删除某一角色的中的某一种权限:先查询该角色所拥有的权限,然后for遍历删除对应的权限 */ @Test public void deleteRole(){ Session session = SessionFactoryUtils.getSession(); Transaction tx = session.beginTransaction(); try { tx.begin(); Role role = (Role)session.get(Role.class, 9); Set<Function> funs = role.getFuns(); /*for (Iterator iterator = funs.iterator(); iterator.hasNext();) { Function function = (Function) iterator.next(); if(function.getFid() == 10){ iterator.remove(); break; } } */ for (Function function : funs) { //删除set中对应的权限 if(function.getFid() == 11){ funs.remove(function);//移除set中的此权限 break;//注意:这里必须要break,这与set集合中删除时游标有关 } } //在重新更新此角色的权限列表 role.setFuns(funs); session.update(role); tx.commit(); } catch (Exception e) { // TODO: handle exception tx.rollback(); e.printStackTrace(); }finally{ session.close(); } } /** * join fetch 【有set集合,不能用join fetch】 */ @Test public void findRole(){ Session session = SessionFactoryUtils.getSession(); List<Role> roles = session.createQuery("from Role").list(); session.close(); for (Role role : roles) { System.out.println(role.getRname()); if(role.getFuns().size() > 0){ for (Function fun: role.getFuns()) { System.out.println(fun.getFname()); } } } } }
标签:
原文地址:http://www.cnblogs.com/ysq0908/p/4761903.html