多对多实体映射

发布于 2022-10-15 10:07:39 字数 4329 浏览 17 评论 0

转:nanguogood

多对多实体映射

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

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

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

先看一下我们设计的User与Server类:

代码: User.java

  1. package com;
  2. import java.util.*;
  3. public class User {
  4. private long id;
  5. private String name;
  6. private Set servers = new HashSet();
  7. }

复制代码代码: Server.java

  1. package com;
  2. import java.util.*;
  3. public class Server {
  4. private long id;
  5. private String address;
  6. private Set users = new HashSet();
  7. }

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

首先来看看User.hbm.xml:

代码:

  1. <?xml version="1.0" encoding='UTF-8'?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
  4. <hibernate-mapping>
  5. <class name="com.User" table="USER">
  6. <id name="id" column="USER_ID" unsaved-value="0">
  7. <generator class="increment"/>
  8. </id>
  9. <property name="name">
  10. <column name="NAME" length="16" not-null="true"/>
  11. </property>
  12. <set name="servers"
  13. table="USER_SERVER"
  14. cascade="save-update">
  15. <key column="USER_ID"/>
  16. <many-to-many class="com.Server"
  17. column="SERVER_ID"/>
  18. </set>
  19. </class>
  20. </hibernate-mapping>

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

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

代码:

  1. <?xml version="1.0" encoding='UTF-8'?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
  4. <hibernate-mapping>
  5. <class name="com.Server" table="SERVER">
  6. <id name="id" column="SERVER_ID" unsaved-value="0">
  7. <generator class="increment"/>
  8. </id>
  9. <property name="address" type="string"/>
  10. <set name="users"
  11. table="USER_SERVER"
  12. inverse="true"
  13. cascade="save-update">
  14. <key column="SERVER_ID"/>
  15. <many-to-many class="com.User"
  16. column="USER_ID"/>
  17. </set>
  18. </class>
  19. </hibernate-mapping>

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文