结论:大多数情况下,操作哪一方级联保存性能都差不多,但是如果是将一个对象添加进多个对象中的时候,这时候在少的一端进行操作,性能会高点。具体看测试类第10个例子
多对多
1、关系操作
1、多对多,谁操作效率都一样(例10例外)
2、解除关系
把第三张表的一行数据删除掉
3、建立关系
把第三张表的数据增加一行记录
4、变更关系
先删除后增加
2、级联操作
都是对象针对集合的操作
Student
public class Student implements Serializable{
private Long sid;
private String sname;
private String description;
private Set<Teacher> teachers;//多对多
public Long getSid() {
return sid;
}
public void setSid(Long sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<Teacher> getTeachers() {
return teachers;
}
public void setTeachers(Set<Teacher> teachers) {
this.teachers = teachers;
}
}
Student.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.xxc.many2many.Student">
<id name="sid" type="long" length="5">
<column name="sid"/>
<generator class="identity"/>
</id>
<property name="sname" type="string" length="20"/>
<property name="description" type="string" length="100"/>
<set name="teachers" table="student_teacher" cascade="all">
<key>
<column name="sid"/>
</key>
<many-to-many class="com.xxc.many2many.Teacher" column="tid"/>
</set>
</class>
</hibernate-mapping>
Teacher
public class Teacher implements Serializable {
private Long tid;
private String tname;
private String description;
private Set<Student> students;多对多
public Long getTid() {
return tid;
}
public void setTid(Long tid) {
this.tid = tid;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
Teacher.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.xxc.many2many.Teacher">
<id name="tid" type="long">
<column name="tid" length="5"/>
<generator class="identity"/>
</id>
<property name="tname" type="string" length="20"/>
<property name="description" type="string" length="100"/>
<!--
配置多对多映射:
table表示第三张表
key column 写当前映射文件所映射的那个类的主键
many-to-many 写的是多对多 对应的那个类,column也是写对应的那个类的主键
-->
<set name="students" inverse="false" cascade="all" table="student_teacher">
<key>
<column name="tid"/>
</key>
<many-to-many class="com.xxc.many2many.Student" column="sid"/>
</set>
</class>
</hibernate-mapping>
Many2Many测试
/**
* 1、新建老师的同时新建学生 级联
* 2、已经存在一个老师,新建一个学生,建立老师和学生之间的关系
* 3、已经存在一个学生,新建一个老师,建立老师和学生之间的关系
* 4、已经存在一个老师,已经存在一个学生,建立关联
* 5、把已经存在的一些学生加入到已经存在的一个老师中
* 6、把一个学生加入到一些老师中
* 7、把多个学生加入到多个老师中
* 8、把一个已经存在的学生从一个已经的老师中移除
* 9、把一些学生从一个已经存在的老师中移除
* 10、把一个学生从一个老师转向到另外一个老师
* 11、删除老师
* 12、删除学生
*/
public class many2ManyTest {
private static SessionFactory sessionFactory;
static{
Configuration con = new Configuration().configure();
sessionFactory = con.buildSessionFactory();
}
/**
* 1.新建老师的同时新建学生 级联
*/
@Test
public void test1(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Teacher tea = new Teacher();
tea.setTname("老师一");
tea.setDescription("1");
Student stu = new Student();
stu.setSname("学生1");
stu.setDescription("1");
Set<Student> stus = new HashSet<Student>();
stus.add(stu);
tea.setStudents(stus);
session.save(tea);
transaction.commit();
session.close();
}
/**
* 2.已经存在一个老师,新建一个学生,建立老师和学生之间的关系
*/
@Test
public void test2(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Teacher tea = (Teacher) session.get(Teacher.class, 1L);
Student stu = new Student();
stu.setSname("学生2");
stu.setDescription("2");
tea.getStudents().add(stu);
transaction.commit();
session.close();
}
/**
* 3.已经存在一个学生,新建一个老师,建立老师和学生之间的关系
*/
@Test
public void test3(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student stu = (Student) session.get(Student.class, 1L);
Teacher tea = new Teacher();
tea.setTname("老师2");
tea.setDescription("2");
stu.getTeachers().add(tea);
transaction.commit();
session.close();
}
/**
* 4.已经存在一个老师,已经存在一个学生,建立关联
*/
@Test
public void test4(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student stu = (Student) session.get(Student.class, 1L);
Teacher tea = (Teacher) session.get(Teacher.class, 2L);
stu.getTeachers().add(tea);
transaction.commit();
session.close();
}
/**
* 5、把已经存在的一些学生加入到已经存在的一个老师中
*/
@Test
public void test5(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Query query = session.createQuery("from Student where id in(1,2,3)");
List<Student> list_stu = query.list();
Teacher tea = (Teacher) session.get(Teacher.class, 2L);
tea.getStudents().addAll(list_stu);
transaction.commit();
session.close();
}
/**
* 6、把一个学生加入到一些老师中
*/
@Test
public void test6(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Query query = session.createQuery("from Teacher where id in(1,2,3)");
List<Teacher> list_tea = query.list();
Student stu = (Student) session.get(Student.class, 1L);
stu.getTeachers().addAll(list_tea);
transaction.commit();
session.close();
}
/**
* 7、把多个学生加入到多个老师中
*/
@Test
public void test7(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Query query_tea = session.createQuery("from Teacher where id in(1,2,3)");
List<Teacher> list_tea = query_tea.list();
Query query_stu = session.createQuery("from Student where id in(1,2,3)");
List<Student> list_stu = query_stu.list();
for(Teacher t : list_tea){
t.getStudents().addAll(list_stu);
}
transaction.commit();
session.close();
}
/**
* 8、把一个已经存在的学生从一个已经的老师中移除
*/
@Test
public void test8(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student stu = (Student) session.get(Student.class, 1L);
Teacher tea = (Teacher) session.get(Teacher.class, 2L);
tea.getStudents().remove(stu);
transaction.commit();
session.close();
}
/**
* 9、把一些学生从一个已经存在的老师中移除
*/
@Test
public void test9(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Query query_stu = session.createQuery("from Student where id in(1,2,3)");
List<Student> list_stu = query_stu.list();
Teacher tea = (Teacher) session.get(Teacher.class, 2L);
for(Student stu : list_stu){
tea.getStudents().remove(stu);
}
transaction.commit();
session.close();
}
/**
* 10(1)、把一个学生从一个老师转向到另外一个老师(在学生端操作)
* Hibernate: select student0_.sid as sid0_0_, student0_.sname as sname0_0_, student0_.description as descript3_0_0_ from Student student0_ where student0_.sid=?
* Hibernate: select teacher0_.tid as tid2_0_, teacher0_.tname as tname2_0_, teacher0_.description as descript3_2_0_ from Teacher teacher0_ where teacher0_.tid=?
* Hibernate: select teacher0_.tid as tid2_0_, teacher0_.tname as tname2_0_, teacher0_.description as descript3_2_0_ from Teacher teacher0_ where teacher0_.tid=?
* Hibernate: select teachers0_.sid as sid0_1_, teachers0_.tid as tid1_, teacher1_.tid as tid2_0_, teacher1_.tname as tname2_0_, teacher1_.description as descript3_2_0_ from student_teacher teachers0_ inner join Teacher teacher1_ on teachers0_.tid=teacher1_.tid where teachers0_.sid=?
* Hibernate: delete from student_teacher where sid=? and tid=?
* Hibernate: insert into student_teacher (sid, tid) values (?, ?)
*/
@Test
public void test10_1(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student stu = (Student) session.get(Student.class, 1L);
Teacher tea1 = (Teacher) session.get(Teacher.class, 1L);
Teacher tea2 = (Teacher) session.get(Teacher.class, 2L);
stu.getTeachers().remove(tea1);
stu.getTeachers().add(tea2);
transaction.commit();
session.close();
}
/**
* 10(2)、把一个学生从一个老师转向到另外一个老师(在教师端操作) 由于每个不同的老师都要getStudents所以相比于10(1)会多查询一次数据库
* Hibernate: select student0_.sid as sid0_0_, student0_.sname as sname0_0_, student0_.description as descript3_0_0_ from Student student0_ where student0_.sid=?
* Hibernate: select teacher0_.tid as tid2_0_, teacher0_.tname as tname2_0_, teacher0_.description as descript3_2_0_ from Teacher teacher0_ where teacher0_.tid=?
* Hibernate: select teacher0_.tid as tid2_0_, teacher0_.tname as tname2_0_, teacher0_.description as descript3_2_0_ from Teacher teacher0_ where teacher0_.tid=?
* Hibernate: select students0_.tid as tid2_1_, students0_.sid as sid1_, student1_.sid as sid0_0_, student1_.sname as sname0_0_, student1_.description as descript3_0_0_ from student_teacher students0_ inner join Student student1_ on students0_.sid=student1_.sid where students0_.tid=?
* Hibernate: select students0_.tid as tid2_1_, students0_.sid as sid1_, student1_.sid as sid0_0_, student1_.sname as sname0_0_, student1_.description as descript3_0_0_ from student_teacher students0_ inner join Student student1_ on students0_.sid=student1_.sid where students0_.tid=?
* Hibernate: delete from student_teacher where tid=?
* Hibernate: insert into student_teacher (tid, sid) values (?, ?)
*/
@Test
public void test10_2(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student stu = (Student) session.get(Student.class, 1L);
Teacher tea1 = (Teacher) session.get(Teacher.class, 1L);
Teacher tea2 = (Teacher) session.get(Teacher.class, 2L);
tea1.getStudents().remove(stu);
tea2.getStudents().add(stu);
transaction.commit();
session.close();
}
/**
* 11、删除老师
*/
@Test
public void test11(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Teacher tea1 = (Teacher) session.get(Teacher.class, 1L);
session.delete(tea1);
transaction.commit();
session.close();
}
/**
* 12、删除学生
*/
@Test
public void test12(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student stu3 = (Student) session.get(Student.class, 3L);
session.delete(stu3);
transaction.commit();
session.close();
}
}