实体的多对多映射,一般采用抽取第三张表的方式来解决,不论是单向关联还是双向关联都是这么做的,把两个表的关系放在第三张表中进行维护。
一、实体
有个用户实体user和角色实体role,一个角色可以有多个用户,一个用户可以有多个角色,那么这两个实体间的关系就是多对多。
Role:
public class Role {
private int id;
private String name;
public int getId() {
return id;
}
//省略get、set
}
User:
public class User {
private int id;
private String name;
private Set roles;//持有role的set
//省略get、set
}
二、创建映射文件
Role.hbm.xml:只是单纯的映射,不维护关系,单向关联
<hibernate-mapping>
<class name="com.tgb.hibernate.Role" table="t_role">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
</class>
</hibernate-mapping>
User.hbm.xml:维护实体的多对多关系
<hibernate-mapping>
<class name="com.tgb.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.tgb.hibernate.Role" column="role_id" />
</set>
</class>
</hibernate-mapping>
生成的数据表:
t_user_role表结构:
这个中间表维护了user和role的关系。
三、双向关联
双向关联只需要Role持有user的set集合,再把Role.hbm.xml中也维护两个实体的多对多关系:
<hibernate-mapping>
<class name="com.tgb.hibernate.Role" table="t_role">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<set name="users" table="t_user_role">
<key column="role_id" not-null="true"/>
<many-to-many class="com.tgb.hibernate.User" column="user_id"/>
</set>
</class>
</hibernate-mapping>
Role.hbm.xml和User.hbm.xml结构基本一致,注意两个维护关系的中间表名称必须一样,生成中间表的字段必须一样。
四、测试添加数据:
public void testSave1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Role r1 = new Role();
r1.setName("总经理");
session.save(r1);
Role r2 = new Role();
r2.setName("人力主管");
session.save(r2);
Role r3 = new Role();
r3.setName("商务经理");
session.save(r3);
Role r4 = new Role();
r4.setName("程序员");
session.save(r4);
User u1 = new User();
u1.setName("张三");
Set u1Roles = new HashSet();
u1Roles.add(r1);
u1Roles.add(r2);
u1.setRoles(u1Roles);
session.save(u1);
User u2 = new User();
u2.setName("李四");
Set u2Roles = new HashSet();
u2Roles.add(r1);
u2Roles.add(r2);
u2Roles.add(r3);
u2.setRoles(u2Roles);
session.save(u2);
User u3 = new User();
u3.setName("王五");
Set u3Roles = new HashSet();
u3Roles.add(r3);
u3Roles.add(r4);
u3.setRoles(u3Roles);
session.save(u3);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
测试结果:
t_role:
t_user:
t_role_user: