多对多实体映射

假设现在有UserServer两个类,一个User可以被授权使用多台Server,而在Server上也记录授权使用它的使用者,就UserServer两者而言即使多对多的关系。

在程序设计时,基本上是不建议直接在UserServer之间建立多对多关系,这会使得UserServer相互依赖,通常会通过一个中介类来维护两者之间的多对多关系,避免两者的相互依赖。

如果一定要直接建立UserServer之间的多对多关系,Hibernate也是支援的,基本上只要您了解之前介绍的几个实体映射,建立多对多关联在配置上并不困难。

先看一下我们设计的UserServer类:

代码:

 

 1 User.java
 2 package com;
 3 import java.util.*;
 4 public class User {
 5 private long id;
 6 private String name;
 7 private Set servers = new HashSet();
 8 }
 9 代码: Server.java
10 package com;
11 import java.util.*;
12 public class Server {
13 private long id;
14 private String address;
15 private Set users = new HashSet();
16 }

 

这儿各使用HashSet来保存彼此的关系,在多对多关系映射上,我们可以建立单向或双向关系,这儿直接介绍双向关系映射,并藉由设定inverse="true",将关系的维护交由其中一方来维护,这么作的结果,在原始码的撰写上,也比较符合Java的对象关系维护,也就是双方都要设置至对方的参考。

首先来看看User.hbm.xml

代码:

<?xml version="1.0" encoding='UTF-8'?>
<!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.User" table="USER">
<id name="id" column="USER_ID" unsaved-value="0">
<generator class="increment"/>
</id>
<property name="name">
<column name="NAME" length="16" not-null="true"/>
</property>
<set name="servers"
table="USER_SERVER"
cascade="save-update">
<key column="USER_ID"/>
<many-to-many class="com.Server"
column="SERVER_ID"/>
</set>
</class>
</hibernate-mapping>

 

在数据库中,数据表之间的多对多关系是通过一个中介的数据表来完成,例如在这个例子中,USER数据表与USER_SERVER数据表是一对多,而USER_SERVERSERVER是多对一,从而完成USERSERVER的多对多关系,在USER_SERVER数据表中,将会有USER_IDSERVER_ID共同作为主键,USER_ID作为一个至USER的外键参考,而SERVER_ID作为一个至SERVER的外键参考。

来看看Server.hbm.xml映射文件:

代码:

<?xml version="1.0" encoding='UTF-8'?>
<!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.Server" table="SERVER">
<id name="id" column="SERVER_ID" unsaved-value="0">
<generator class="increment"/>
</id>
<property name="address" type="string"/>
<set name="users"
table="USER_SERVER"
inverse="true"
cascade="save-update">
<key column="SERVER_ID"/>
<many-to-many class="com.User"
column="USER_ID"/>
</set>
</class>
</hibernate-mapping>

 

设置上与User.hbm.xml是类似的,只是增加了inverse="true",表示将关系的维护交由另一端,注意我们在UserServercascade都是设置为save-update,在多对多的关系中,alldeletecascade是没有意义的,因为多对多中,并不能因为父对象被删除,而造成被包括的子对象被删除,因为可能还有其它的父对象参考至这个子对象。

 

 

完!

posted @ 2011-04-14 09:39  饮露秋林  阅读(602)  评论(0编辑  收藏  举报