多对多双向关联:数据库中有一张students表(字段 id和name),teachers表(字段id和name) 还有一张关联表 s_t(字段id 外键stu_id(参考students表的id)和tea_id(参考teachers表的id))
类图如下:Student中还存在一个teachers 的集合

Students.java
package com.org.model;
import java.util.Set;
public class Students {
private int id;
private String name;
private Set<Teacher> teachers;//多对多关系一般有一个中间表用于相关联,Hibernate面向对象,更注重于对象关系
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Teacher> getTeachers() {
return teachers;
}
public void setTeachers(Set<Teacher> teachers) {
this.teachers = teachers;
}
}
Teacher.java
package com.org.model;
import java.util.Set;
public class Teacher {
private int id;
private String name;
private Set<Students> students;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Students> getStudents() {
return students;
}
public void setStudents(Set<Students> students) {
this.students = students;
}
}
Students.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.org.model">
<class name="Students" table="students" >
<id name="id">
<generator class="native"/>
</id>
<property name="name" not-null="true"/>
<!-- set标签中的name用于指定映射的集合类型(即为Students类中多方对应的属性名 )
key标签中的column为s_t表中参照students表的外键-->
<set name="teachers" cascade="save-update" inverse="true" table="s_t">
<key column="stu_id" not-null="true"></key>
<!-- class表明set中放的是什么类型的集合,column指定s_t表中参照teacher表的外键 -->
<many-to-many class="Teacher" column="tea_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
Teacher.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.org.model">
<class name="Teacher" table="teachers" >
<id name="id">
<generator class="native"/>
</id>
<property name="name" not-null="true"/>
<!-- set标签中的name用于指定映射的集合类型(即为Teacher类中多方对应的属性名 )
key标签中的column为s_t表中参照teacher表的外键-->
<set name="students" cascade="save-update" table="s_t">
<key column="tea_id" not-null="true"></key>
<!-- class表明set中放的是什么类型的集合,column指定s_t表中参照students表的外键 -->
<many-to-many class="Students" column="stu_id"></many-to-many>
</set>
</class>
</hibernate-mapping>
hibernate.cfg.xml
<mapping resource="com/org/model/Students.hbm.xml" /> <mapping resource="com/org/model/Teacher.hbm.xml" />
测试类:
package com.org.model.test;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.org.model.Students;
import com.org.model.Teacher;
import com.org.util.HibernateUtil;
public class HibernateTest2 {
@Test
public void testSave1() {
Session session = null;
Transaction tx = null;
try {
// 拿到session
session = HibernateUtil.getSession();
// 开启事务
tx = session.beginTransaction();
// 给实体赋值
Set<Teacher> ts = new HashSet<Teacher>();
Teacher t1 = new Teacher();
t1.setName("XiangfGang1");
ts.add(t1);
Teacher t2 = new Teacher();
t2.setName("ZhengHui1");
ts.add(t2);
Teacher t3 = new Teacher();
t3.setName("WangJinFeng1");
ts.add(t3);
Set<Students> ss = new HashSet<Students>();
Students sd1 = new Students();
sd1.setName("ChengHai1");
ss.add(sd1);
Students sd2 = new Students();
sd2.setName("JiangKui1");
ss.add(sd2);
Students sd3 = new Students();
sd3.setName("YanJiaYang1");
ss.add(sd3);
t1.setStudents(ss);
t2.setStudents(ss);
t3.setStudents(ss);
session.save(t1);
session.save(t2);
session.save(t3);
// 告诉学生有哪些老师,与上面告诉老师有哪些学生任选一种即可
// sd1.setTeachers(ts);
// sd2.setTeachers(ts);
// sd3.setTeachers(ts);
// session.save(sd1);
// session.save(sd2);
// session.save(sd3);
// 提交事务
tx.commit();
} catch (Exception e) {
// 打印堆栈信息
e.printStackTrace();
// 事务回滚
if (tx != null) {
tx.rollback();
}
} finally {
HibernateUtil.closeSession(session);
}
}
}
结果:
Hibernate: insert into teachers (name) values (?)
Hibernate: insert into students (name) values (?)
Hibernate: insert into students (name) values (?)
Hibernate: insert into students (name) values (?)
Hibernate: insert into teachers (name) values (?)
Hibernate: insert into teachers (name) values (?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
Hibernate: insert into s_t (tea_id, stu_id) values (?, ?)
因为中间表的关系由Teacher端维护,所以插入Teacher的时候会插入关联关系。只能一段来维护关系,不能两端同时维护关系,这样会导致在中间表出现重复插入的现象。
本文介绍了一种数据库中常见的多对多关联关系,并通过具体的Java类和Hibernate配置文件展示了如何实现这种关系。同时,提供了测试类代码示例,演示了如何保存数据。

被折叠的 条评论
为什么被折叠?



