多对多的关系使我们经常遇到的,下面来说一下如何使用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属性。