JPA多对多
维护端注解
@ManyToMany (cascade = CascadeType.REFRESH)
@JoinTable (//关联表
name = "student_teacher" , //关联表名
inverseJoinColumns = @JoinColumn (name = "teacher_id" ),//被维护端外键
joinColumns = @JoinColumn (name = "student_id" ))//维护端外键
被维护端注解
@ManyToMany(
cascade = CascadeType.REFRESH,
mappedBy = "teachers",//通过维护端的属性关联
fetch = FetchType.LAZY)
关系维护端删除时,如果中间表存在些纪录的关联信息,则会删除该关联信息;
关系被维护端删除时,如果中间表存在些纪录的关联信息,则会删除失败 .
以学生和老师的对应关系为例。一个学生可以拥有多个老师,一个老师也可以拥有多个学生。
学生实体类
- package com.taoistwar.jpa.entity.manytomany;
- import java.util.HashSet;
- import java.util.Set;
- import javax.persistence.CascadeType;
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.GeneratedValue;
- import javax.persistence.GenerationType;
- import javax.persistence.Id;
- import javax.persistence.JoinColumn;
- import javax.persistence.JoinTable;
- import javax.persistence.ManyToMany;
- @Entity
- public class Student {
- private Integer id;
- private String name;
- private Set<Teacher> teachers = new HashSet<Teacher>();
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- @Column(nullable = false, length = 16 )
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- @ManyToMany(cascade = CascadeType.REFRESH)
- @JoinTable(name = "student_teacher" , inverseJoinColumns = @JoinColumn(name = "teacher_id" ), joinColumns = @JoinColumn(name = "student_id" ))
- public Set<Teacher> getTeachers() {
- return teachers;
- }
- public void setTeachers(Set<Teacher> teachers) {
- this.teachers = teachers;
- }
- public void addTeacher(Teacher teacher) {
- this.teachers.add(teacher);
- }
- public void removeTeachers(Teacher teacher) {
- this.teachers.remove(teacher);
- }
- }
package com.taoistwar.jpa.entity.manytomany; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; @Entity public class Student { private Integer id; private String name; private Set<Teacher> teachers = new HashSet<Teacher>(); @Id @GeneratedValue(strategy = GenerationType.AUTO) public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Column(nullable = false, length = 16) public String getName() { return name; } public void setName(String name) { this.name = name; } @ManyToMany(cascade = CascadeType.REFRESH) @JoinTable(name = "student_teacher", inverseJoinColumns = @JoinColumn(name = "teacher_id"), joinColumns = @JoinColumn(name = "student_id")) public Set<Teacher> getTeachers() { return teachers; } public void setTeachers(Set<Teacher> teachers) { this.teachers = teachers; } public void addTeacher(Teacher teacher) { this.teachers.add(teacher); } public void removeTeachers(Teacher teacher) { this.teachers.remove(teacher); } }
重点在于:
- @ManyToMany (cascade = CascadeType.REFRESH)
- @JoinTable (name = "student_teacher" , inverseJoinColumns = @JoinColumn (name = "teacher_id" ), joinColumns = @JoinColumn (name = "student_id" ))
- public Set<Teacher> getTeachers() {
- return teachers;
- }
@ManyToMany(cascade = CascadeType.REFRESH) @JoinTable(name = "student_teacher", inverseJoinColumns = @JoinColumn(name = "teacher_id"), joinColumns = @JoinColumn(name = "student_id")) public Set<Teacher> getTeachers() { return teachers; }
老师实体类
- package com.taoistwar.jpa.entity.manytomany;
- 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.GenerationType;
- import javax.persistence.Id;
- import javax.persistence.ManyToMany;
- @Entity
- public class Teacher {
- private Integer id;
- private String name;
- private Set<Student> students = new HashSet<Student>();
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- @Column(nullable = false, length = 16 )
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- @ManyToMany(cascade = CascadeType.REFRESH, mappedBy = "teachers" , fetch = FetchType.LAZY)
- public Set<Student> getStudents() {
- return students;
- }
- public void setStudents(Set<Student> students) {
- this.students = students;
- }
- @Override
- public int hashCode() {
- final int prime = 31 ;
- int result = 1 ;
- result = prime * result + ((id == null) ? 0 : id.hashCode());
- return result;
- }
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Teacher other = (Teacher) obj;
- if (id == null) {
- if (other.id != null)
- return false;
- } else if (!id.equals(other.id))
- return false;
- return true;
- }
- }
package com.taoistwar.jpa.entity.manytomany; 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.GenerationType; import javax.persistence.Id; import javax.persistence.ManyToMany; @Entity public class Teacher { private Integer id; private String name; private Set<Student> students = new HashSet<Student>(); @Id @GeneratedValue(strategy = GenerationType.AUTO) public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Column(nullable = false, length = 16) public String getName() { return name; } public void setName(String name) { this.name = name; } @ManyToMany(cascade = CascadeType.REFRESH, mappedBy = "teachers", fetch = FetchType.LAZY) public Set<Student> getStudents() { return students; } public void setStudents(Set<Student> students) { this.students = students; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((id == null) ? 0 : id.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Teacher other = (Teacher) obj; if (id == null) { if (other.id != null) return false; } else if (!id.equals(other.id)) return false; return true; } }
重点在于:
- @ManyToMany (cascade = CascadeType.REFRESH, mappedBy = "teachers" , fetch = FetchType.LAZY)
- public Set<Student> getStudents() {
- return students;
- }
@ManyToMany(cascade = CascadeType.REFRESH, mappedBy = "teachers", fetch = FetchType.LAZY) public Set<Student> getStudents() { return students; }
拥有mappedBy注解的实体类为关系被维护端,另外的实体类为关系维护端的。顾名思意,关系的维护端对关系(在多对多为中间关联表)的CRUD做操作。关系的被维护端没有该操作,不能维护关系。
测试类
- package com.taoistwar.jpa.entity.manytomany;
- import javax.persistence.EntityManager;
- import javax.persistence.EntityManagerFactory;
- import javax.persistence.Persistence;
- import org.junit.Test;
- public class ManyToMany {
- @Test
- public void save() {
- EntityManagerFactory emf = Persistence
- .createEntityManagerFactory( "JPAPU" );
- EntityManager em = emf.createEntityManager();
- em.getTransaction().begin();
- Student student = new Student();
- student.setName( "小李" );
- Teacher teacher = new Teacher();
- teacher.setName( "大李" );
- em.persist(student);
- em.persist(teacher);
- em.getTransaction().commit();
- emf.close();
- }
- @Test
- public void bind() {
- EntityManagerFactory emf = Persistence
- .createEntityManagerFactory( "JPAPU" );
- EntityManager em = emf.createEntityManager();
- em.getTransaction().begin();
- Student student = em.find(Student. class , 1 );
- Teacher teacher = em.find(Teacher. class , 1 );
- student.addTeacher(teacher);
- em.persist(student);
- em.getTransaction().commit();
- emf.close();
- }
- @Test
- public void unbind() {
- EntityManagerFactory emf = Persistence
- .createEntityManagerFactory( "JPAPU" );
- EntityManager em = emf.createEntityManager();
- em.getTransaction().begin();
- Student student = em.find(Student. class , 1 );
- Teacher teacher = em.find(Teacher. class , 1 );
- student.removeTeachers(teacher);
- em.persist(student);
- em.getTransaction().commit();
- emf.close();
- }
- @Test
- public void removeTeacher() {
- EntityManagerFactory emf = Persistence
- .createEntityManagerFactory( "JPAPU" );
- EntityManager em = emf.createEntityManager();
- em.getTransaction().begin();
- // 关系被维护端删除时,如果中间表存在些纪录的关联信息,则会删除失败
- em.remove(em.getReference(Teacher. class , 1 ));
- em.getTransaction().commit();
- emf.close();
- }
- @Test
- public void removeStudent() {
- EntityManagerFactory emf = Persistence
- .createEntityManagerFactory( "JPAPU" );
- EntityManager em = emf.createEntityManager();
- em.getTransaction().begin();
- // 关系维护端删除时,如果中间表存在些纪录的关联信息,则会删除该关联信息
- em.remove(em.getReference(Student. class , 1 ));
- em.getTransaction().commit();
- emf.close();
- }
- }