维护端注解
@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)
关系维护端删除时,如果中间表存在些纪录的关联信息,则会删除该关联信息;
关系被维护端删除时,如果中间表存在些纪录的关联信息,则会删除失败 .
以学生和老师的对应关系为例。一个学生可以拥有多个老师,一个老师也可以拥有多个学生。
学生实体类
Student.java代码
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 teachers = new HashSet(); @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 getTeachers() { return teachers; } public void setTeachers(Set 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 getTeachers() { return teachers; }
Teacher.java代码
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 students = new HashSet(); @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 getStudents() { return students; } public void setStudents(Set 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 getStudents() { return students; }
拥有mappedBy注解的实体类为关系被维护端,另外的实体类为关系维护端的。顾名思意,关系的维护端对关系(在多对多为中间关联表)的CRUD做操作。关系的被维护端没有该操作,不能维护关系。