首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hibernate 3 學習筆記(二十):多對多關聯映射實戰

     編輯:Java 相關知識

資料庫設計:中介表模式

多對多關係在關聯式資料庫中無法直接表達,必須引入**中介表** 將其拆解為兩個一對多關係。

多對多 ER 圖

CREATE TABLE user (
    id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL DEFAULT ''
);

CREATE TABLE server (
    id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
    address VARCHAR(100) NOT NULL DEFAULT ''
);

CREATE TABLE user_server (
    user_id INT(11),
    server_id INT(11)
);

實體類別

public class User {
    private Integer id;
    private String name;
    private Set<Server> servers = new HashSet<>();
    // getter/setter ...
}

public class Server {
    private Integer id;
    private String address;
    private Set<User> users = new HashSet<>();
    // getter/setter ...
}

映射檔關鍵點:雙向 <many-to-many>

User.hbm.xml(關係維護端)

<set name="servers" table="user_server" cascade="save-update">
    <key column="user_id"/>
    <many-to-many class="com.hb3.pack_19.model.Server" column="server_id"/>
</set>

Server.hbm.xml(inverse="true" 放棄維護權)

<set name="users" table="user_server" inverse="true" cascade="save-update">
    <key column="server_id"/>
    <many-to-many class="com.hb3.pack_19.model.User" column="user_id"/>
</set>
核心原則: 雙向關聯必須指定一方 inverse="true",避免重複維護中介表導致效能損耗或資料不一致。通常由 **集合端(這裡是 User.servers)負責維護**。

測試代碼:建立雙向關聯並持久化

Server s1 = new Server(); s1.setAddress("PC-219"); s1.setUsers(new HashSet<>());
Server s2 = new Server(); s2.setAddress("PC-220"); s2.setUsers(new HashSet<>());
Server s3 = new Server(); s3.setAddress("PC-221"); s3.setUsers(new HashSet<>());

User u1 = new User(); u1.setName("shenbin"); u1.setServers(new HashSet<>());
User u2 = new User(); u2.setName("chenyan"); u2.setServers(new HashSet<>());

// 雙向建立關聯(雙邊都要 set,否則記憶體中物件圖不一致)
u1.getServers().add(s1); u1.getServers().add(s2); u1.getServers().add(s3);
s1.getUsers().add(u1); s2.getUsers().add(u1); s3.getUsers().add(u1);

u2.getServers().add(s1); u2.getServers().add(s3);
s1.getUsers().add(u2); s3.getUsers().add(u2);

Transaction tx = session.beginTransaction();
session.save(u1); // 因 cascade="save-update",關聯的 Server 及中介表資料會一併存入
session.save(u2);
tx.commit();

效能與設計建議

雖然 Hibernate 支援多對多映射,但**中介表會導致查詢需多一次 JOIN**,寫入時也需維護三張表。**實務上建議盡量避免多對多**,改用兩個一對多關聯,並在中介表建立實體類別,獲得更靈活的控制與更佳效能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved