接上文:
多对多关系的映射:思路
多对多关系是通过一个中间表或者说关联表来实现的,即两个多对一关系的综合就是一个多对多;
1 :首先确定好关系的维护端和被维护端;ManyToMany注解标识多对多对应的字段;
指定关系的维护端是通过JoinTable注解来实现的,这个注解可以指定关联表的名称,
和关联表的字段名称,其中joinColumns指定关系维护端这个字段对应于关联表的字段名称
inverseJoinColumns:这个注解可以指定关系被维护端对应于关联表的字段名称,当然这两个注解
都是JoinTable里面的参数;
关系的被维护端,是通过mappedBy来指定的;
2
关系的被维护端的更新操作,我们必须先调用关系维护端的方法解除关联关系,然后再调用持久化
api进行更新操作;否则会抛出异常;
不多说,直接上例子:一个老师可以有多个学生,一个学生可以有多个老师,那么这就是一中多对多的关系表;
package cn.itcast.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
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 Gender gender = Gender.MAN;
private Set<Teacher> teachers = new HashSet<Teacher>();
@Enumerated(EnumType.STRING)
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(name = "name", length = 10)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToMany(cascade = CascadeType.REFRESH)
@JoinTable(name = "student_teacher", joinColumns = @JoinColumn(name = "student_id"), inverseJoinColumns = @JoinColumn(name = "teacher_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 removeTeacher(Teacher teacher) {
//为了判断某个元 是否在某个集合中,即只要id不同就是不同的对象;需要以id覆盖hashcode和equals方法;
if (this.teachers.contains(teacher)) {
this.teachers.remove(teacher);
}
}
}
package cn.itcast.domain;
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.Id;
import javax.persistence.ManyToMany;
@Entity
public class Teacher {
private Integer id;
private String name;
private Set<Student> students = new HashSet<Student>();
@Id
@GeneratedValue
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;
}
@ManyToMany(cascade = CascadeType.REFRESH, mappedBy = "teachers", fetch = FetchType.LAZY)
//mappedBy:指定关系被维护端;
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 cn.itcast.domain;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
public class TestManyToMany {
public static void main(String[] args) {
buildTS();
//deleteStudent();
}
private static void save() {
EntityManagerFactory factory = Persistence
.createEntityManagerFacto ry("itcast");
EntityManager entityManager = factory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Student student=new Student();
Teacher teacher=new Teacher();
student.setName("吴杰");
teacher.setName("陈老师");
//将老师对象持久化
entityManager.persist(teacher);
//将学生对象持久化
entityManager.persist(student);
transaction.commit();
entityManager.close();
factory.close();
}
private static void buildTS(){
EntityManagerFactory factory = Persistence
.createEntityManagerFacto ry("itcast");
EntityManager entityManager = factory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
//取出学生对象;
Student student=entityManager.getReference(Student.class, 1);
//取出老师对象;
Teacher teacher=entityManager.getReference(Teacher.class, 1);
//建立学生和老师之间的关系;由于学生表是关系的维护端, 此建立关系是有学生表负责的;
student.addTeacher(teacher);
transaction.commit();
entityManager.close();
factory.close();
}
private static void removeTS(){
EntityManagerFactory factory = Persistence
.createEntityManagerFacto ry("itcast");
EntityManager entityManager = factory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
//取出学生对象;
Student student=entityManager.getReference(Student.class, 1);
//取出老师对象;
Teacher teacher=entityManager.getReference(Teacher.class, 1);
//解除学生和老师之间的关系;由于学生表是关系的维护端, 此接触关系是由学生表负责的;
student.removeTeacher(teacher);
transaction.commit();
entityManager.close();
factory.close();
}
private static void deleteTeacher(){
EntityManagerFactory factory = Persistence
.createEntityManagerFacto ry("itcast");
EntityManager entityManager = factory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
//取出学生对象;
Student student=entityManager.getReference(Student.class, 1);
//取出老师对象;
Teacher teacher=entityManager.getReference(Teacher.class, 1);
//解除学生和老师之间的关系;由于学生表是关系的维护端, 此接触关系是由学生表负责的;
//student.removeTeacher(teacher);
entityManager.remove(teacher);
transaction.commit();
entityManager.close();
factory.close();
}
private static void deleteStudent(){
EntityManagerFactory factory = Persistence
.createEntityManagerFacto ry("itcast");
EntityManager entityManager = factory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
//取出学生对象;
Student student=entityManager.getReference(Student.class, 1);
entityManager.remove(student);
transaction.commit();
entityManager.close();
factory.close();
}
}
不得不说,上面有很多重复代码。记住多对多的映射思路,即拆分为两个一对多,出现了中间表,千万记住一句话,关系的维护端负责外键字段的更新,被维护端是没有权限更新外键字段的。
历史上的今天
热度
在LOFTER的更多文章
接上文:
\r\n多对多关系的映射:思路
多对多关系是通过一个中间表或者说关联表来实现的,即两个多对一关系的综合就是一个多对多;
1 :首先确定好关系的维护端和被维护端;ManyToMany注解标识多对多对应的字段;
指定关系的维护端是通过JoinTable注解来实现的,这个注解可以指定关联表的名称,
和关联表的字段名称,其中joinColumns指定关系维护端这个字段对应于关联表的字段名称
inverseJoinColumns:这个注解可以指定关系被维护端对应于关联表的字段名称,当然这两个注解
都是JoinTable里面的参数;
关系的被维护端,是通过mappedBy来指定的;
2
关系的被维护端的更新操作,我们必须先调用关系维护端的方法解除关联关系,然后再调用持久化
评论