Hibernate多對多示例
假設現在有User與Server兩個類別,一個User可以被授權使用多臺Server,而在Server上也記錄授權使用它的使用者,就User與Server兩者而言即使多對多的關係。
在程式設計時,基本上是不建議直接在User與Server之間建立多對多關係,這會使得User與Server相互依賴,通常會透過一個中介類別來維護兩者之間的多對多關係,避免兩者的相互依賴。
如果一定要直接建立User與Server之間的多對多關係,Hibernate也是支援的,基本上只要您瞭解之前介紹的幾個實體對映,建立多對多關聯在配置上並不困難。
先看一下我們設計的User與Server類別:
- 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;
- }
- }
- 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 version="1.0"?>
- PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
- ">
- <hibernate-mapping>
- <class name="onlyfun.caterpillar.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="onlyfun.caterpillar.Server"
- column="SERVER_ID"/>
- set>
- class>
- 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 version="1.0"?>
- PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
- ">
- <hibernate-mapping>
- <class name="onlyfun.caterpillar.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="onlyfun.caterpillar.User"
- column="USER_ID"/>
- set>
- class>
- hibernate-mapping>
設定上與User.hbm.xml是類似的,只是增加了inverse="true",表示將關係的維護交由另一端,注意我們在User與Server的cascade都是設定為save-update,在多對多的關係中,all、delete等cascade是沒有意義的,因為多對多中,並不能因為父物件被刪除,而造成被包括的子物件被刪除,因為可能還有其它的父物件參考至這個子物件。
我們使用下面這個程式來測試:
- 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 |
+-----------------+-------------+
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/800861/viewspace-922099/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 基於MyEclipse的Hibernate的多對一和一對多操作簡單示例Eclipse
- hibernate(四) 雙向多對多對映關係
- 6.Hibernate多對多關係建立
- hibernate中多對多關係的維護
- hibernate一對多、多對多的實體設計和配置檔案配置
- hibernate(三) 一對多對映關係
- 關於Hibernate多層1對多關係查詢
- Hibernate對映檔案一對多關係薦
- [增刪改查] 最規範的 JPA 一對多/多對一 CRUD 示例
- Hibernate繼承對映多型的詳解繼承多型
- MyBatis表關聯 一對多 多對一 多對多MyBatis
- Mybatis【一對多、多對一、多對多】知識要點MyBatis
- Hibernate學習(三)一對多資料的儲存
- Hibernate中有一對多關係,如何插入資料呢
- 關於Hibernate一對多關聯儲存問題
- Hibernate annotation, JPA如何對映多個屬性為unique
- JPA(3) 表關聯關係(多對一、一對多、多對多、一對一)
- gorm 關係一對一,一對多,多對多查詢GoORM
- Ext.data.association.hasMany一對多模型使用示例ASM模型
- mybatis的一對多,多對一,以及多對對的配置和使用MyBatis
- Mybatis一對多、多對一處理MyBatis
- mybatis一對多&&多對一處理MyBatis
- MyBatis07-(多對一、一對多)MyBatis
- Mybatis09_一對一、一對多、多對多、延遲載入MyBatis
- Spring Data JPA 之 一對一,一對多,多對多 關係對映Spring
- Hibernate 多執行緒問題!執行緒
- JPA(hibernate)一對多根據多的一方某屬性進行過濾查詢
- 7.Hibernate一對多關係建立與錯誤解決
- HIBERNATE裡面怎麼繼承一對多的關係呢繼承
- hibernate之關於使用連線表實現多對一關聯對映
- spring data jpa關聯查詢(一對一、一對多、多對多)Spring
- mybatis入門基礎(六)----高階對映(一對一,一對多,多對多)MyBatis
- Laravel多對多模型關聯Laravel模型
- 多對多的操作問題
- JPA中對映關係詳細說明(一對多,多對一,一對一、多對多)、@JoinColumn、mappedBy說明APP
- Kafka 1.0.0 多消費者示例Kafka
- python多執行緒示例Python執行緒
- 多執行緒程式碼示例執行緒