多对多的关系使我们经常遇到的,下面来说一下如何使用Hibernate来描述这种关联关系。
在使用ER来描述时,我们通常会抽出一种表来描述他们的关系,同样的,在进行关联映射时我们也采用这样的方式。描述如下:
说明:多对多关联映射,即对象之间多与多的关系,一般需要引入第三个实体来描述他们的关系,通过外键组合成第三张表。实例如下:
实体类:(get和set方法省略)
User.java:
public class User {
private int id;
private String name;
//使用set集合,关联role
private Set role;
}
Role.java:
public class Role {
private int id;
private String name;
//通过set集合,关联user
private Set user;
}
映射文件:
User.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.tgb.hibernate.User" table="t_user_many2many">
<id name="id">
<generator class="native"/>
</id>
<!-- name值是实体类中引入的role集合名词 -->
<!-- 组成第三张表名为t_user_role -->
<set name="role" table="t_user_role">
<!-- 设置外键 -->
<key column="user_id" not-null="true"/>
<!-- 关联Role -->
<many-to-many class="com.tgb.hibernate.Role" column="role_id"/>
</set>
</class>
</hibernate-mapping>
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.tgb.hibernate.Role" table="t_role_many2many">
<id name="id">
<generator class="native"/>
</id>
<property name="name" />
<!-- name值是实体类中引入的user集合名词 -->
<!-- 组成第三张表名为t_user_role -->
<set name="user" table="t_user_role">
<!-- 设置外键 -->
<key column="role_id" not-null="true"/>
<!-- 关联User -->
<many-to-many class="com.tgb.hibernate.User" column="user_id"/>
</set>
</class>
</hibernate-mapping>
编写测试类,进行数据维护:
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.setRole(u1Roles);
session.save(u1);
User u2 = new User();
u2.setName("李四");
Set u2Roles = new HashSet();
u2Roles.add(r1);
u2Roles.add(r2);
u2Roles.add(r3);
u2.setRole(u2Roles);
session.save(u2);
session.getTransaction().commit();
}
catch(Exception e){
e.printStackTrace();
session.getTransaction().rollback();
}
finally{
HibernateUtils.closeSession(session);
}
}
注意:
使用<set>标签进行管理关系设置,合成第三张表。
由<key>标签进行外键的设置。
使用<many-to-many>标签进行关联。
多对多关联,一般最好是由一端来进行数据的维护,即在某一段设置inverse属性。