学生和老师就是多对多的关系。一个学生有多个老师,一个老师教多个学生。多对多映射采取中间表连接的映射策略,建立的中间表将分别引入两边的主键作为外键。jpa 对于中间表的元数据提供了可配置的方式,用户可以自定义中间表的表名,列名。
下面就以学生和老师为例介绍多对多映射关系的实例开发
Student实体类
package com.ljq.entity;import java.util.HashSet; import java.util.Set;import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToMany;@SuppressWarnings("serial") @Entity public class Student implements java.io.Serializable {/** 学生ID **/private Integer studentid;/** 学生姓名 **/private String name;private Set<Teacher> teachers=new HashSet<Teacher>();public Student() {super();}public Student(String name) {super();this.name = name;}@Id@GeneratedValuepublic Integer getStudentid() {return studentid;}public void setStudentid(Integer studentid) {this.studentid = studentid;}@Column(nullable=false,length=32)public String getName() {return name;}public void setName(String name) {this.name = name;}//@ManyToMany注释表示Student是多对多关系的一边,mappedBy属性定义了Student为双向关系的维护端//Teacher表是关系的维护者,owner side,有主导权,它有个外键指向Student表。 @ManyToMany(mappedBy = "students")public Set<Teacher> getTeachers() {return teachers;}public void setTeachers(Set<Teacher> teachers) {this.teachers = teachers;}}
Teacher实体类
package com.ljq.entity;import java.util.HashSet; import java.util.Set;import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany;@SuppressWarnings("serial") @Entity public class Teacher implements java.io.Serializable {/** 教师ID **/private Integer teacherid;/** 教师姓名 **/private String name;private Set<Student> students=new HashSet<Student>();public Teacher() {super();}public Teacher(String name) {super();this.name = name;}@Id@GeneratedValuepublic Integer getTeacherid() {return teacherid;}public void setTeacherid(Integer teacherid) {this.teacherid = teacherid;}@Column(nullable=false,length=32)public String getName() {return name;}public void setName(String name) {this.name = name;}//@ManyToMany注释表示Teacher是多对多关系的一端。//@JoinTable描述了多对多关系的数据表关系。name属性指定中间表名称,joinColumns定义中间表与Teacher表的外键关系。//中间表Teacher_Student的Teacher_ID列是Teacher表的主键列对应的外键列,inverseJoinColumns属性定义了中间表与另外一端(Student)的外键关系。 @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)@JoinTable(name = "Teacher_Student", joinColumns = { @JoinColumn(name = "Teacher_ID", referencedColumnName = "teacherid") }, inverseJoinColumns = { @JoinColumn(name = "Student_ID", referencedColumnName = "studentid") })public Set<Student> getStudents() {return students;}public void setStudents(Set<Student> students) {this.students = students;}/*** 添加学生* * @param student*/public void addStudent(Student student) {if (!this.students.contains(student)) {this.students.add(student);student.setTeacher(this);}}/*** 删除学生* * @param student*/public void removeStudent(Student student) {if(this.students.contains(student)){student.setTeacher(null);this.students.remove(student);}} }
ManyToManyTest测试类
package com.ljq.test;import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence;import org.junit.Test;import com.ljq.entity.Student; import com.ljq.entity.Teacher;public class ManyToManyTest {@Testpublic void save() {EntityManagerFactory factory = Persistence.createEntityManagerFactory("ljq");EntityManager em=factory.createEntityManager();em.getTransaction().begin();em.persist(new Teacher("张老师"));em.persist(new Student("小张"));em.getTransaction().commit();em.close();factory.close();}/*** 为老师添加一个学生**/@Testpublic void build() {EntityManagerFactory factory = Persistence.createEntityManagerFactory("ljq");EntityManager em=factory.createEntityManager();em.getTransaction().begin();Teacher teacher = em.find(Teacher.class, 2);teacher.addStudent(em.getReference(Student.class, 2));em.getTransaction().commit();em.close();factory.close();}/*** 解除学生跟老师的关系**/@Testpublic void remove() {EntityManagerFactory factory = Persistence.createEntityManagerFactory("ljq");EntityManager em=factory.createEntityManager();em.getTransaction().begin();Teacher teacher = em.find(Teacher.class, 2);teacher.removeStudent(em.getReference(Student.class, 2));em.getTransaction().commit();em.close();factory.close();}/*** 删除学生,因为学生不是关系维护者,所以需要先手工解除老师与学生的关联,然后再删除学生**/@Testpublic void deleteStudent() {EntityManagerFactory factory = Persistence.createEntityManagerFactory("ljq");EntityManager em=factory.createEntityManager();em.getTransaction().begin();Teacher teacher = em.find(Teacher.class, 2);Student student = em.getReference(Student.class, 2);teacher.removeStudent(student); //手工解除老师与学生的关系 em.remove(student); //删除学生 em.getTransaction().commit();em.close();factory.close();}/*** 删除老师,因为老师是关系维护者,所以可以直接解除老师与学生的关系,不用我们手工解除**/@Testpublic void deleteTeacher() {EntityManagerFactory factory = Persistence.createEntityManagerFactory("ljq");EntityManager em=factory.createEntityManager();em.getTransaction().begin();em.remove(em.getReference(Teacher.class, 3));em.getTransaction().commit();em.close();factory.close();}/*** 用来判断映射是否成功* */@Testpublic void test() {EntityManagerFactory factory = Persistence.createEntityManagerFactory("ljq");factory.close();}}