JPA关联关系映射

xiaoxiao2021-02-28  161

JPA关联关系映射

JavaEE API文档:http://docs.oracle.com/javaee/7/api/

关联关系从整体上分为单向关联和双向关联

单向关联:只需从一端访问另一端,如教师Teacher可访问学生Student,则Teacher实体需要包含类型为Student的属性

双向关联:两端均可互相访问,如教师Teacher可访问学生Student,学生Student也可访问教师Teacher,两个实体均需要包含类型为对方的属性

关联关系细分为如下几种

单向1-1:需要在控制关系的一方实体中使用注解@OneToOne、@JoinColumn标注类型为对方的属性。如教师Teacher端为控制关系的一方,则Teacher实体如下: public class Teacher{ @OneToOne(cascade|fetch|targetEntity) //每个选项可取值可查阅API @JoinColumn(name="student_no") //name指定外键列 private Student student; } Teacher表中应该有一列student_no,Student实体不需要任何注解,也不包含类型为Teacher的属性。如果指定了相应的级联属性,则持久化Teacher时可同时持久化Student 单向1-N:需要在控制关系的一方实体中使用注解@OneToMany、@JoinColumn标注类型为对方的集合属性。如教师Teacher端为控制关系的一方,则Teacher实体如下 public class Teacher{ @OneToMany(cascade|fetch|targetEntity) //每个选项可取值可查阅API @JoinColumn(name="teacher_no") //name指定外键列,这里注意指定的是teacher_no,下面会说明 private Set<Student> students = new HashSet<>(); } Teacher表中不会有student_no,Student表中应该有teacher_no,因为Teacher是1的一端,即主表,JPA会自动为合适的数据表增加外键列。Student实体不需要任何注解,也不包含类型为Teacher的属性。如果指定了相应的级联属性,则持久化Teacher时可同时持久化Student 单向N-1:需要在控制关系的一方实体中使用注解@ManyToOne、@JoinColumn标注类型为对方的属性。如教师Teacher端为控制关系的一方,则Teacher实体如下 public class Teacher{ @ManyToOne(cascade|fetch|targetEntity) //每个选项可取值可查阅API @JoinColumn(name="student_no") //name指定外键列 private Student student; } Teacher表中应该有一列student_no,Student实体不需要任何注解,也不包含类型为Teacher的属性。如果指定了相应的级联属性,则持久化Teacher时可同时持久化Student 单向N-N:需要在控制关系的一方实体中使用注解@ManyToMany、@JoinTable标注类型为对方的属性,这里应该是一个集合属性。如教师Teacher端为控制关系的一方,则Teacher实体如下 public class Teacher{ @ManyToMany(cascade|fetch|targetEntity) //每个选项可取值可查阅API @JoinTable(name="teacher_student",joinColumns=@JoinColumn(name="teacher_no"),inverseJoinColumns=@JoinColumn(name="student_no")) //name指定连接表,也就是除Teacher和Student之外的第三个表,由它来维护关系。joinColumns指定当前实体的主键,inverseJoinColumns指定关联实体的主键 private Set<Student> students = new HashSet<>(); } teacher_student表中应该包含两列teacher_no和student_no,Student实体不需要任何注解,也不包含类型为Teacher的属性。如果指定了相应的级联属性,则持久化Teacher时可同时持久化Student 双向1-1:双方均要包含类型为对方的集合属性,控制关系的一方需要使用注解@OneToOne、@JoinColumn标注类型为对方的属性,不控制关系的一方需要在@OneToOne中指定mappedBy选项。如教师Teacher端为控制关系的一方,则Teacher实体和Student实体如下 public class Teacher{ @OneToOne(cascade|fetch|targetEntity) //每个选项可取值可查阅API @JoinColumn(name="student_no") //name指定外键列 private Student student; } public class Student{ @OneToOne(mappedBy="student",cascade|fetch|targetEntity) //mappedBy指明这端不控制关系,其他每个选项可取值可查阅API private Teacher teacher; } Teacher表中应该有一列student_no,Student表中不会有teacher_no。如果指定了相应的级联属性,则持久化Teacher时可同时持久化Student

- 双向1-N(N-1):1的一端需要使用注解@OneToMany标注类型为对方的集合属性,同时指定mappedBy属性表示1的一端不控制关系,N的一端则需要使用注解@ManyToOne、@JoinColumn标注类型为对方的属性。如学生Student端为控制关系的一方,则Teacher实体和Student实体如下

public class Teacher{ @OneToMany(mappedBy="teacher",cascade|fetch|targetEntity) //mappedBy指明这端不控制关系,其他每个选项可取值可查阅API private Set<Student> students = new HashSet<>(); } public class Student{ @ManyToOne(cascade|fetch|targetEntity) //每个选项可取值可查阅API @JoinColumn(name="teacher_no") //name指定外键列 private Teacher teacher; } Student表中应该有一列teacher_no,如果指定了相应的级联属性,则持久化Student时可同时持久化Tacher

- 双向N-N:双方均要包含类型为对方的集合属性,控制关系的一方需要使用注解@ManyToMany、@JoinTable标注类型为对方的集合属性,不控制关系的一方需要在@ManyToMany中指定mappedBy选项。如教师Teacher端为控制关系的一方,则Teacher实体和Student实体如下

public class Teacher{ @ManyToMany(cascade|fetch|targetEntity) //每个选项可取值可查阅API @JoinTable(name="teacher_student",joinColumns=@JoinColumn(name="teacher_no"),inverseJoinColumns=@JoinColumn(name="student_no")) //name指定连接表,也就是除Teacher和Student之外的第三个表,由它来维护关系。joinColumns指定当前实体的主键,inverseJoinColumns指定关联实体的主键 private Set<Student> students = new HashSet<>(); } public class Student{ @ManyToMany(mappedBy="students",cascade|fetch|targetEntity) //mappedBy指明这端不控制关系,其他每个选项可取值可查阅API private Set<Teacher> teachers = new HashSet<>(); } teacher_student表中应该包含两列teacher_no和student_no,如果指定了相应的级联属性,则持久化Teacher时可同时持久化Student

最后,建议尽量显示指定targetEntity,第一可避免包含集合属性时未加泛型信息而出错;第二可以提升性能,因为默认情况下JPA会通过反射判断关联实体的类型。

JavaEE API文档:http://docs.oracle.com/javaee/7/api/

转载请注明原文地址: https://www.6miu.com/read-35145.html

最新回复(0)