主控方:Student.java
package com.yazuo.entity.annotation.manyToMany;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
@Entity
@Table(name="student")
@SequenceGenerator(name="student_id_seq",sequenceName="student_id_seq",allocationSize=1)
public class Student implements Serializable{
/**
*
*/
private static final long serialVersionUID = -573567772201838862L;
@Id
@GeneratedValue(generator="student_id_seq",strategy=GenerationType.SEQUENCE)
private Integer id;
private String name;
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name="teacher_student",
joinColumns={@JoinColumn(name="student_id")},
inverseJoinColumns={@JoinColumn(name="teacher_id")})
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;
}
}
被控方:Teacher.java
package com.yazuo.entity.annotation.manyToMany;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
@Entity
@Table(name="teacher")
@SequenceGenerator(name="teacher_id_seq",sequenceName="teacher_id_seq",allocationSize=1)
public class Teacher implements Serializable{
/**
*
*/
private static final long serialVersionUID = 7442402280500664820L;
@Id
@GeneratedValue(generator="teacher_id_seq",strategy=GenerationType.SEQUENCE)
private Integer id;
private String name;
@ManyToMany(mappedBy="teachers",cascade=CascadeType.ALL)
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;
}
}
Test.java
package com.yazuo.entity.annotation.manyToMany;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
public class Test {
@org.junit.Test
public void add() throws Exception {
AnnotationConfiguration cfg = new AnnotationConfiguration();
SessionFactory sf = cfg.configure().buildSessionFactory();
Session session = sf.openSession();
Teacher teacher1 = new Teacher();
Teacher teacher2 = new Teacher();
Student student1 = new Student();
Student student2 = new Student();
teacher1.setName("teacher1");
teacher2.setName("teacher2");
student1.setName("student1");
student2.setName("student2");
// Set<Teacher> teachers =student1.getTeachers();
// teachers.add(teacher1);
// teachers.add(teacher2);
Set<Teacher> teachers = new HashSet<Teacher>();
teachers.add(teacher1);
student1.setTeachers(teachers);
//
// Set<Teacher> teachers1 = new HashSet<Teacher>();
// teachers.add(teacher1);
student2.setTeachers(teachers);
Set<Student> students = new HashSet<Student>();
students.add(student1);
students.add(student2);
teacher1.setStudents(students);
/*
* joinTable 在 student ,student为主表,session.save(student) 会在中间表保存 teacher
* 反之 session.save(teacher) 不会再中间表保存 student
*/
session.save(teacher1);
session.flush();
session.close();
sf.close();
}
@org.junit.Test
public void findStudent() throws Exception {
AnnotationConfiguration configuration = new AnnotationConfiguration();
SessionFactory sf = configuration.configure().buildSessionFactory();
Session session = sf.openSession();
String hql = "from Student s where s.id = 1";
Student student = (Student) session.createQuery(hql).uniqueResult();
System.out.println(student.getName());
// System.out.println(student.getTeachers().size());
session.flush();
session.close();
sf.close();
}
@org.junit.Test
public void findTeacher() throws Exception {
AnnotationConfiguration configuration = new AnnotationConfiguration();
SessionFactory sf = configuration.configure().buildSessionFactory();
Session session = sf.openSession();
String hql = "from Teacher t where t.id = 1";
Teacher teacher = (Teacher) session.createQuery(hql).uniqueResult();
System.out.println(teacher.getName());
// System.out.println(teacher.getStudents().size());
session.flush();
session.close();
sf.close();
}
@org.junit.Test
public void deleteStudent() throws Exception {
AnnotationConfiguration configuration = new AnnotationConfiguration();
SessionFactory sf = configuration.configure().buildSessionFactory();
Session session = sf.openSession();
String hql = "from Student s where s.id = 5";
Student student = (Student) session.createQuery(hql).uniqueResult();
// String hql = "delete from Student s where s.id = 2"; 报错,违反外键约束
// session.createQuery(hql).executeUpdate();
student.setTeachers(null); //即清空中间表,而不删除 teacher,student 里面的数据
session.update(student);
session.flush();
session.close();
sf.close();
}
@org.junit.Test
public void deleteTeacher() throws Exception {
AnnotationConfiguration configuration = new AnnotationConfiguration();
SessionFactory sf = configuration.configure().buildSessionFactory();
Session session = sf.openSession();
String hql = "from Teacher t where t.id = 8";
Teacher teacher = (Teacher) session.createQuery(hql).uniqueResult();
// String hql = "delete from Student s where s.id = 2"; 报错,违反外键约束
// session.createQuery(hql).executeUpdate();
teacher.setStudents(null); //被控方不会清空中间表
session.update(teacher);
session.flush();
session.close();
sf.close();
}
}
小结:
多对多 cascade 有特殊的地方
在一对一,一对多关系中,没有中间表,只要有 cascade,将一方作为属性保存到另一方,都会成功保存到数据库(person.setHouse(house))
但是在双向多对多关系中
在主控方加入 cascade,然后 session.save(student1); 即可将数据保存到中间表
在被控方加入 cascade, session.save(teacher1); 只会在 teacher表,和student表插入数据,而不会在中间表插入数据
还要显示的 student1.setTeacher(teacher),student1.setTeacher(teacher) 才会在中间表插入数据
总结即为:主控方:我中有你即可。被控方:我中有你,你中有我才行
主控方:
session.save(student1)
Student student1 = new Student();
Teacher teacher1 = new Teacher();
Teacher teacher2 = new Teacher();
Set<Teacher> teachers = new HashSet<Teacher>();
teachers.add(teacher1);
teachers.add(teacher2);
student1.setTeacher(teachers);
被控方:
session.save(teacher1);
Teacher teacher1 = new Teacher();
Student student1 = new Student();
Student student2 = new Student();
Set<Teacher> teachers = new HashSet<Teacher>();
teachers.add(teacher1);
Set<Student> students = new HashSet<Student>();
students.add(student1);
students.add(student2);
student1.setTeacher(teachers);
student2.setTeacher(teachers);
teacher1.setStudent(students);
这样中间表才有数据