hibernate多对多关系维护
直接以老师与学生的关系为例。在多对多关联关系中,其中一方都可通过Set保留另一方的所有信息,这样的关联是双向关联。在多对多关联关系中,也只能是双向关联。老师和学生分别对应一张表,通过一张有双方id的中间表来维护多对多的关联。
实体类
[java]?view plain?copy
package?test.hibernate.hbmManyToMany;??
import?java.util.HashSet;??
import?java.util.Set;??
public?class?Teacher?{??
private?Integer?id;??
private?String?name;??
private?Set<Student>?students?=?new?HashSet<Student>();??
public?Integer?getId()?{??
return?id;??
}??
public?void?setId(Integer?id)?{??
this.id?=?id;??
}??
public?String?getName()?{??
return?name;??
}??
public?void?setName(String?name)?{??
this.name?=?name;??
}??
public?Set<Student>?getStudents()?{??
return?students;??
}??
public?void?setStudents(Set<Student>?students)?{??
this.students?=?students;??
}??
@Override??
public?String?toString()?{??
//?TODO?Auto-generated?method?stub??
return?"[Teacher:id="?+?id?+?",name="?+?name?+?"]";??
}??
}??
[java]?view plain?copy
package?test.hibernate.hbmManyToMany;??
import?java.util.HashSet;??
import?java.util.Set;??
public?class?Student?{??
private?Integer?id;??
private?String?name;??
private?Set<Teacher>?teachers?=?new?HashSet<Teacher>();??
public?Integer?getId()?{??
return?id;??
}??
public?void?setId(Integer?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;??
}??
@Override??
public?String?toString()?{??
//?TODO?Auto-generated?method?stub??
return?"[Student:id="?+?id?+?",name="?+?name?+?"]";??
}??
}??
Student.hbm.xml
[html]?view plain?copy
<?xml?version="1.0"?>??
<!DOCTYPE?hibernate-mapping?PUBLIC??
"-//Hibernate/Hibernate?Mapping?DTD?3.0//EN"??
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">??
<hibernate-mapping?package="test.hibernate.hbmManyToMany">??
<class?name="Student"?table="student">??
<id?name="id"?type="integer"?column="id">??
<generator?class="native"?/>??
</id>??
<property?name="name"?/>??
<!--?inverse属性:默认为false,表示本方维护关联关系;?如果设为true,表示本方不维护关联关系?只是影响是否能设置外键列的值(设成有效值或是null值),对获取信息没有影响?-->??
<set?name="teachers"?table="teacher_student">??
<key?column="studentId"></key>??
<many-to-many?class="Teacher"?column="teacherId"></many-to-many>??
</set>??
</class>??
</hibernate-mapping>??
在多对多关系中,可在Set里通过inverse设置只有其中一方维护。
Teacher.hbm.xml
[html]?view plain?copy
<?xml?version="1.0"?>??
<!DOCTYPE?hibernate-mapping?PUBLIC??
"-//Hibernate/Hibernate?Mapping?DTD?3.0//EN"??
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">??
<hibernate-mapping?package="test.hibernate.hbmManyToMany">??
<class?name="Teacher"?table="teacher">??
<id?name="id"?type="integer"?column="id">??
<generator?class="native"?/>??
</id>??
<property?name="name"?/>??
<set?name="students"?table="teacher_student">??
<key?column="teacherId"></key>??
<many-to-many?class="Student"?column="studentId"></many-to-many>??
</set>??
</class>??
</hibernate-mapping>??
测试类
[java]?view plain?copy
package?test.hibernate.hbmManyToMany;??
import?org.hibernate.Session;??
import?org.hibernate.SessionFactory;??
import?org.hibernate.cfg.Configuration;??
import?org.junit.Test;??
public?class?App?{??
private?static?SessionFactory?sessionFactory?=?new?Configuration()//??
.configure()//??
.addClass(Teacher.class)//?添加Hibernate实体类(加载对应的映射文件)??
.addClass(Student.class)//??
.buildSessionFactory();??
@Test??
public?void?testSave()?throws?Exception?{??
Session?session?=?sessionFactory.openSession();??
session.beginTransaction();??
//?--------------------------------------------??
//?构建对象??
Teacher?teacher1?=?new?Teacher();??
teacher1.setName("林老师");??
Teacher?teacher2?=?new?Teacher();??
teacher2.setName("张老师");??
Student?student1?=?new?Student();??
student1.setName("李明");??
Student?student2?=?new?Student();??
student2.setName("刘备");??
teacher1.getStudents().add(student1);??
teacher1.getStudents().add(student2);??
teacher2.getStudents().add(student1);??
teacher2.getStudents().add(student2);??
//?下面部分不能与上面的代码块同时进行,只能选择其中一部分,不然会抛出在中间表中重复插入相同记录的异常??
//?如果两边都要写,注意设置其中一方的inverse为true??
//?student1.getTeachers().add(teacher1);??
//?student1.getTeachers().add(teacher2);??
//?student2.getTeachers().add(teacher1);??
//?student2.getTeachers().add(teacher2);??
//?保存??
session.save(teacher1);??
session.save(teacher2);??
session.save(student1);??
session.save(student2);??
//?--------------------------------------------??
session.getTransaction().commit();??
session.close();??
}??
//?获取到部门关联的员工??
@Test??
public?void?testGet()?throws?Exception?{??
Session?session?=?sessionFactory.openSession();??
session.beginTransaction();??
//?获取数据??
Teacher?teacher?=?(Teacher)?session.get(Teacher.class,?4);??
System.out.println(teacher);??
System.out.println(teacher.getStudents());??
session.getTransaction().commit();??
session.close();??
}??
//?解除关联关系??
@Test??
public?void?testRemoveRelation()?throws?Exception?{??
Session?session?=?sessionFactory.openSession();??
session.beginTransaction();??
//?--------------------------------------------??
//?如果Teacher.hbm.xml中inverse=false就可以删除,否则不可以删除??
Teacher?teacher?=?(Teacher)?session.get(Teacher.class,?4);??
teacher.getStudents().clear();??
//?--------------------------------------------??
session.getTransaction().commit();??
session.close();??
}??
//?删除部门及对员工的影响??
@Test??
public?void?testDelete()?throws?Exception?{??
Session?session?=?sessionFactory.openSession();??
session.beginTransaction();??
//?--------------------------------------------??
//?会同时删除teacher_student和teacher中教师id=4的记录??
Teacher?teacher?=?(Teacher)?session.get(Teacher.class,?4);??
session.delete(teacher);??
//?--------------------------------------------??
session.getTransaction().commit();??
session.close();??
}??
} ?
请点击输入图片描述
执行testGet方法时控制台内容
请点击输入图片描述
当然了