Chinaunix首页 | 论坛 | 博客
  • 博客访问: 442887
  • 博文数量: 161
  • 博客积分: 5005
  • 博客等级: 上校
  • 技术积分: 1090
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-20 16:38
文章分类

全部博文(161)

文章存档

2011年(21)

2010年(33)

2009年(89)

2008年(18)

我的朋友

分类: Java

2009-04-25 21:48:55

假設現在有User與Server兩個類別,一個User可以被授權使用多台Server,而在Server上也記錄授權使用它的使用者,就User與Server兩者而言即使多對多的關係。

在程式設計時,基本上是不建議直接在User與Server之間建立多對多關係,這會使得User與Server相互依賴,通常會透過一個中介類別來維護兩者之間的多對多關係,避免兩者的相互依賴。

如果一定要直接建立User與Server之間的多對多關係,Hibernate也是支援的,基本上只要您瞭解之前介紹的幾個實體映射,建立多對多關聯在配置上並不困難。

先看一下我們設計的User與Server類別:

java 代码
package onlyfun.caterpillar;

import java.util.*;

public class User {
private long id;
private String name;
private Set servers = new HashSet();

public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set getServers() {
return servers;
}

public void setServers(Set servers) {
this.servers = servers;
}
}
java 代码
package onlyfun.caterpillar;

import java.util.*;

public class Server {
private long id;
private String address;
private Set users = new HashSet();

public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Set getUsers() {
return users;
}
public void setUsers(Set users) {
this.users = users;
}
}
這邊各使用HashSet來保存彼此的關係,在多對多關係映射上,我們可以建立單向或雙向關係,這邊直接介紹雙向關係映射,並藉由設定 inverse="true",將關係的維護交由其中一方來維護,這麼作的結果,在原始碼的撰寫上,也比較符合Java的物件關係維護,也就是雙方都要設 置至對方的參考。

首先來看看User.hbm.xml:

xml 代码
xml version="1.0"?>

PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"">





table="USER_SERVER"
cascade="save-update">


column="SERVER_ID"/>

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映射文件:

xml 代码
xml version="1.0"?>

PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"">



table="USER_SERVER"
inverse="true"
cascade="save-update">


column="USER_ID"/>

設置上與User.hbm.xml是類似的,只是增加了inverse="true",表示將關係的維護交由另一端,注意我們在User與 Server的cascade都是設置為save-update,在多對多的關係中,all、delete等cascade是沒有意義的,因為多對多中, 並不能因為父物件被刪除,而造成被包括的子物件被刪除,因為可能還有其它的父物件參考至這個子物件。

我們使用下面這個程式來測試:

java 代码
import onlyfun.caterpillar.*;
import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;

public class HibernateTest {
public static void main(String[] args) throws HibernateException {
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

Server server1 = new Server();
server1.setAddress("PC-219");
Server server2 = new Server();
server2.setAddress("PC-220");
Server server3 = new Server();
server3.setAddress("PC-221");

User user1 = new User();
user1.setName("caterpillar");
User user2 = new User();
user2.setName("momor");

user1.getServers().add(server1);
user1.getServers().add(server2);
user1.getServers().add(server3);
server1.getUsers().add(user1);
server2.getUsers().add(user1);
server3.getUsers().add(user1);

user2.getServers().add(server1);
user2.getServers().add(server3);
server1.getUsers().add(user2);
server3.getUsers().add(user2);

Session session = sessionFactory.openSession();
Transaction tx= session.beginTransaction();
session.save(user1);
session.save(user2);

tx.commit();
session.close();

sessionFactory.close();
}
}
注意由於設定了inverse="true",所以必須分別設定User與Server之間的相互參考,來看看實際上資料庫中是如何儲存的:

select * FROM USER

+---------+-------------+
| USER_ID | NAME |
+---------+-------------+
| 1 | caterpillar |
| 2 | momor |
+---------+-------------+

select * FROM USER_SERVER

+-----------------+--------------+
| SERVER_ID | USER_ID |
+-----------------+--------------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 1 | 2 |
| 2 | 2 |
+-----------------+--------------+

select * FROM SERVER

+-----------------+------------+
| SERVER_ID | address |
+-----------------+------------+
| 1 | PC-219 |
| 2 | PC-221 |
| 3 | PC-220 |
+-----------------+-------------+

阅读(663) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~