多對多需兩張實體表 + 一張關聯表。關聯表僅含兩個外鍵欄位,組成複合主鍵,不對應實體類別(無 POJO、無映射檔)。
-- 實體表:使用者
CREATE TABLE `user` (
`userid` VARCHAR(20) PRIMARY KEY,
`name` VARCHAR(20) NOT NULL,
`age` INT NOT NULL,
`birthday` DATE NOT NULL
);
-- 實體表:課程
CREATE TABLE `course` (
`id` INT PRIMARY KEY AUTO_INCREMENT,
`title` VARCHAR(50) NOT NULL,
`description` TEXT NOT NULL,
`course_num` INT NOT NULL
);
-- 關聯表:使用者_課程
CREATE TABLE `user_course` (
`userid` VARCHAR(20) NOT NULL,
`cid` INT NOT NULL,
PRIMARY KEY (`userid`, `cid`),
FOREIGN KEY (`userid`) REFERENCES `user`(`userid`) ON DELETE CASCADE,
FOREIGN KEY (`cid`) REFERENCES `course`(`id`) ON DELETE CASCADE
);
<class name="User" table="user">
<id name="userid" column="userid">
<generator class="assigned"/> <!-- 字串主鍵指派 -->
</id>
<property name="name" column="name"/>
<property name="age" column="age"/>
<property name="birthday" column="birthday"/>
<set name="courses" table="user_course" lazy="true">
<key column="userid"/>
<many-to-many class="Course" column="cid"/>
</set>
</class>
<class name="Course" table="course">
<id name="id" column="id">
<generator class="identity"/> <!-- 自增 -->
</id>
<property name="title" column="title"/>
<property name="description" column="description"/>
<property name="courseNum" column="course_num"/>
<set name="users" table="user_course" inverse="true" lazy="true">
<key column="cid"/>
<many-to-many class="User" column="userid"/>
</set>
</class>
table="user_course":指定關聯表名稱。key column:本方在關聯表的外鍵欄位。many-to-many column:對方在關聯表的外鍵欄位。inverse="true":由另一方維護關聯(雙向關聯必須一方設 true,避免重複 INSERT/DELETE)。lazy="true":預設延遲載入。// 新增關聯
User u = session.get(User.class, "U001");
Course c = session.get(Course.class, 101);
u.getCourses().add(c); // 必須在 inverse="false" 方操作
c.getUsers().add(u); // 同步記憶體端雙向引用
session.saveOrUpdate(u); // 只需儲存維護方
注意:關聯表無額外欄位(如建立時間、狀態)時才用純多對多;若有額外屬性,應將關聯表提升為實體,改為兩組一對多。