多对多关系是比较常见的关系,很多表之间的关系都涉及多对多,比如老师和学生,一个老师可以有很多个学生,一个学生可以有很多个老师。常见的权限管理模块,一个角色可以有很多个功能,一个功能也可以有很多个角色,这是无法仅仅通过两张表就可以指明关系的,通常需要中间表来建立两种表的关系,中间表通常也叫关系表,数据库中书存在的,但是hibernate我们不需要写关系表的类。如下:
类Role 和Function类
public class Role {
private int id;
private String name;
private Set<Function> functions = new HashSet<Function>(0);
//get…set
}
public class Function {
private int id;
private String name;
private String code;
private String url;
public Function() {
// TODO Auto-generated constructor stub
}
public Function(String name, String code, String url) {
super();
this.name = name;
this.code = code;
this.url = url;
}
//get…set }
Role.hbm.xml(重点配置)
<hibernate-mapping package="cn.siggy.pojo">
<class name="Role">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"/>
<!-- 多对多 -->
<set name="functions" table="role_func" cascade="save-update">
<!-- 表示当前类 映射到关系表中的列-->
<key column="rid"/>
<!-- 所对应的另一方在关系表中的列 -->
<many-to-many column="fid" class="Function"/>
</set>
</class>
</hibernate-mapping>
function.hbm.xml
<hibernate-mapping package="cn.siggy.pojo">
<class name="Function">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="code"/>
<property name="url"/>
</class>
</hibernate-mapping>
关系表的外键关系
测试
@Test
public void testSave() throws HibernateException, SerialException, SQLException{
Session session = null;
Transaction tx = null;
try{
session = HibernateUtil.getSession();
tx = session.beginTransaction();
Function f1 = new Function("用户管理","user_mag","userAction");
Function f2 = new Function("角色管理","role_mag","roleAction");
Function f3 = new Function("系统管理","sys_mag","sysAction");
Function f4 = new Function("权限管理","prev_mag","prevAction");
Role r1 = new Role();
r1.setName("admin");
r1.getFunctions().add(f1);
r1.getFunctions().add(f2);
r1.getFunctions().add(f3);
r1.getFunctions().add(f4);
Role r2 = new Role();
r2.setName("vip");
r2.getFunctions().add(f1);
r2.getFunctions().add(f2);
session.save(r1);
session.save(r2);
tx.commit();
}catch (HibernateException e) {
if(tx!=null)
tx.rollback();
e.printStackTrace();
throw e;
}finally{
HibernateUtil.closeSession();
}
}
测试2
@Test
public void testGet(){
Session session = null;
Transaction tx = null;
try{
session = HibernateUtil.getSession();
tx = session.beginTransaction();
Role role = (Role)session.get(Role.class, 1);
System.out.println("角色名:"+role.getName());
System.out.println("该角色所对应的权限:");
for(Iterator<Function> iter = role.getFunctions().iterator();
iter.hasNext();){
Function func = iter.next();
System.out.println(func.getName()+"---"+func.getCode());
}
//取数据
tx.commit();
理解了单向,双向也就方便多了,表还是一样,不过多了双向
Role类不变
public class Role {
private int id;
private String name;
private Set<Function> functions = new HashSet<Function>(0);
//get…set
}
Function因为双向,也多了集合
public class Function {
private int id;
private String name;
private String code;
private String url;
private Set<Role> roles = new HashSet<Role>(0);
public Function() {
// TODO Auto-generated constructor stub
}
public Function(String name, String code, String url) {
super();
this.name = name;
this.code = code;
this.url = url;
}
//get…set }
Role.hbm.xml不变
<hibernate-mapping package="cn.siggy.pojo">
<class name="Role">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"/>
<!-- 多对多 -->
<set name="functions" table="role_func" cascade="save-update">
<!-- 表示当前类 映射到关系表中的列-->
<key column="rid"/>
<!-- 所对应的另一方在关系表中的列 -->
<many-to-many column="fid" class="Function"/>
</set>
</class>
</hibernate-mapping>
function.hbm.xml
注意关系表的名字应该一致,其实就是单向两边都配置,这里inverse由另外一方管理维护关系,只有在集合元素里面才有这个属性inverse
<hibernate-mapping package="cn.siggy.pojo">
<class name="Function">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<property name="code"/>
<property name="url"/>
<set name="roles" table="role_func" inverse="true">
<key column="fid"/>
<many-to-many column="rid" class="Role"/>
</set>
</class>
</hibernate-mapping>