hibernate多对多关联映射同样可以分为单向的关联映射和双向的关联映射,与一对多关联映射相比,双方之间的关系将不再由其中多的一方维护而是变成了由第三张表来维护。第三张表的出现不仅减少了两张表中的数据冗余,而且大大提高了数据存储的灵活性。同样我们将从用户和角色的角度出发从单向和双向两个角度来分析多对多关联映射。
我们假定所给需求为知道用户id可以取得该用户所对应的的角色名称(反过来也一样,同样可以知道角色id可以取得该角色下的所有用户名称),则User类中持有对Role的引用,但是Role不知道User的存在,他们的代码如下:
package com.bjpowernode.hibernate;
import java.util.Set;
public class User {
private int id;
private String name;
private Set roles;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set getRoles() {
return roles;
}
public void setRoles(Set roles) {
this.roles = roles;
}
}
public class Role {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
所对应的的User.hbm.xml文件和Role.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.bjpowernode.hibernate.Role" table="t_role">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
<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="userid"/>
<many-to-many class="com.bjpowernode.hibernate.Role" column="role_id"/>
</set>
</class>
</hibernate-mapping>
从User.hbm.xml文件描述中我们可以看出第三张表t_user_role中的字段由User表和Role表中主键组成,需要尤其注意的是如果将其改为双向关联的话,第一表的名称不能改变,第二表中字段的名称不能改变,因为这两个类(或者说两个表)同时维护着第三张表。与多对一关联关系相比多对多关联关系中hbm.xml文件并没有太大变化,只不过是引入了第三张表,并将<one-to-many>标签改为<many-to-many>标签而已。