Hibernate @OneToMany 注释到底是如何工作的?
How exactly does the Hibernate @OneToMany annotation work?
我是 Hibernate 的新手,我正在学习它的教程。我在理解 OneToMany 注释的工作原理时遇到了一些问题。
所以我有这 2 个实体 classes:Student 代表学生,Guide 代表一个人指导学生。因此,每个学生都与一个向导相关联,但一个向导可以跟随多个学生。我想要一个向导,了解与他相关的学生。
所以我有:
学生:
@Entity
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column(name="enrollment_id", nullable=false)
private String enrollmentId;
private String name;
@ManyToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
@JoinColumn(name="guide_id")
private Guide guide;
public Student() {}
public Student(String enrollmentId, String name, Guide guide) {
this.enrollmentId = enrollmentId;
this.name = name;
this.guide = guide;
}
public Guide getGuide() {
return guide;
}
public void setGuide(Guide guide) {
this.guide = guide;
}
}
所以@ManyToOne guide字段上的注解:
@ManyToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
@JoinColumn(name="guide_id")
private Guide guide;
表示单个向导与单个学生关联,但一个向导可以跟随多个学生。这样对吗?指定的 cascade 设置究竟有什么作用?我认为这意味着当我持久化一个包含 Guide 对象作为字段的 Student 对象时,这个 Guide 对象也会自动持久化。当我删除 Student 对象时,也会发生同样的事情,相关的 Guide 记录也会被删除……但我对此不是很确定。 ..
好的,这样做我将在 Student table 和Guidetable中的一条记录 因为在Studenttable中我会有外键加入Guide table 这样学生就可以知道它的向导,但是这样做,向导就不知道后面的学生...这很不聪明。
要做到这一点,指南 class 是这样实现的:
@Entity
public class Guide {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column(name="staff_id", nullable=false)
private String staffId;
private String name;
private Integer salary;
@OneToMany(mappedBy="guide", cascade={CascadeType.PERSIST})
private Set<Student> students = new HashSet<Student>();
public Guide() {}
public Guide(String staffId, String name, Integer salary) {
this.staffId = staffId;
this.name = name;
this.salary = salary;
}
public Set<Student> getStudents() {
return students;
}
public void setSalary(Integer salary) {
this.salary = salary;
}
public void addStudent(Student student) {
students.add(student);
student.setGuide(this);
}
}
因此,如您所见,此 class 包含:
@OneToMany(mappedBy="guide", cascade={CascadeType.PERSIST})
private Set<Student> students = new HashSet<Student>();
它用于声明双向关系。
所以在我看来,这个注释会自动在 Student table 中创建一个 guide_id 字段表示实现双向关系的外键。
事实上,使用这个映射 Student table 是在我的数据库中以这种方式自动创建的:
'id', 'bigint(20)', 'NO', 'PRI', NULL, 'auto_increment'
'enrollment_id', 'varchar(255)', 'NO', '', NULL, ''
'name', 'varchar(255)', 'YES', '', NULL, ''
'guide_id', 'bigint(20)', 'YES', 'MUL', NULL, ''
所以在 Student 实体 class 中我没有定义 guide_id 字段但是我有它在 Student table 数据库中。所以我认为table中这个字段的创建依赖于之前在Guide实体中定义的@OneToMany注解class。这是正确的还是我遗漏了什么?
是的,您可以定义一个没有双向关联的 @OneToMany
实体,并且添加的列在数据库中的 Many
实体端(即使实体不知道它是链接到 One
端实体)。
您也可以为此使用联接 table,但这不是必需的。
我是 Hibernate 的新手,我正在学习它的教程。我在理解 OneToMany 注释的工作原理时遇到了一些问题。
所以我有这 2 个实体 classes:Student 代表学生,Guide 代表一个人指导学生。因此,每个学生都与一个向导相关联,但一个向导可以跟随多个学生。我想要一个向导,了解与他相关的学生。
所以我有:
学生:
@Entity
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column(name="enrollment_id", nullable=false)
private String enrollmentId;
private String name;
@ManyToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
@JoinColumn(name="guide_id")
private Guide guide;
public Student() {}
public Student(String enrollmentId, String name, Guide guide) {
this.enrollmentId = enrollmentId;
this.name = name;
this.guide = guide;
}
public Guide getGuide() {
return guide;
}
public void setGuide(Guide guide) {
this.guide = guide;
}
}
所以@ManyToOne guide字段上的注解:
@ManyToOne(cascade={CascadeType.PERSIST, CascadeType.REMOVE})
@JoinColumn(name="guide_id")
private Guide guide;
表示单个向导与单个学生关联,但一个向导可以跟随多个学生。这样对吗?指定的 cascade 设置究竟有什么作用?我认为这意味着当我持久化一个包含 Guide 对象作为字段的 Student 对象时,这个 Guide 对象也会自动持久化。当我删除 Student 对象时,也会发生同样的事情,相关的 Guide 记录也会被删除……但我对此不是很确定。 ..
好的,这样做我将在 Student table 和Guidetable中的一条记录 因为在Studenttable中我会有外键加入Guide table 这样学生就可以知道它的向导,但是这样做,向导就不知道后面的学生...这很不聪明。
要做到这一点,指南 class 是这样实现的:
@Entity
public class Guide {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
@Column(name="staff_id", nullable=false)
private String staffId;
private String name;
private Integer salary;
@OneToMany(mappedBy="guide", cascade={CascadeType.PERSIST})
private Set<Student> students = new HashSet<Student>();
public Guide() {}
public Guide(String staffId, String name, Integer salary) {
this.staffId = staffId;
this.name = name;
this.salary = salary;
}
public Set<Student> getStudents() {
return students;
}
public void setSalary(Integer salary) {
this.salary = salary;
}
public void addStudent(Student student) {
students.add(student);
student.setGuide(this);
}
}
因此,如您所见,此 class 包含:
@OneToMany(mappedBy="guide", cascade={CascadeType.PERSIST})
private Set<Student> students = new HashSet<Student>();
它用于声明双向关系。
所以在我看来,这个注释会自动在 Student table 中创建一个 guide_id 字段表示实现双向关系的外键。
事实上,使用这个映射 Student table 是在我的数据库中以这种方式自动创建的:
'id', 'bigint(20)', 'NO', 'PRI', NULL, 'auto_increment'
'enrollment_id', 'varchar(255)', 'NO', '', NULL, ''
'name', 'varchar(255)', 'YES', '', NULL, ''
'guide_id', 'bigint(20)', 'YES', 'MUL', NULL, ''
所以在 Student 实体 class 中我没有定义 guide_id 字段但是我有它在 Student table 数据库中。所以我认为table中这个字段的创建依赖于之前在Guide实体中定义的@OneToMany注解class。这是正确的还是我遗漏了什么?
是的,您可以定义一个没有双向关联的 @OneToMany
实体,并且添加的列在数据库中的 Many
实体端(即使实体不知道它是链接到 One
端实体)。
您也可以为此使用联接 table,但这不是必需的。