关系映射开发(二):一对多映射
- 1.编写实体
- 1.1 新建 School 实体
- 1.2 新建 Teacher 实体
- 2.测试映射关系
单向关系的一对多注解 @oneToMany,只用于关系的发出端(一 的一方)。另外,需要关系的发出端定义一个 集合类型 的接收端的字段属性。
在一对多关联关系映射中,默认是以 中间表 方式来映射这种关系的。中间表的名称为 “用下画线连接关系的 拥有端(发岀端)和 Inverse 端(接收端)”,中间表两个字段分别为两张表的表名加下画线 _
再加主键组成。
当然,也可以改变这种默认的中间表的映方式。在关系的拥有端,使用 @JoinClolum 注解定义外键来映射这个关系。
1.编写实体
下面以学校(School)和老师(Teacher)来演示一对多的映射关系。
1.1 新建 School 实体
@OneToMany 中 One 的一方 School,见以下代码:
package com.example.demo.entity;import lombok.Data;
import javax.persistence.*;
import java.util.List;@Entity
@Data
public class School {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private long id;private String name;// @OneToMany(cascade = CascadeType.ALL)@OneToMany()@JoinColumn(name = "school_id")private List<Teacher> teacherList;
}
1.2 新建 Teacher 实体
@OneToMany 中 Many 的一方 Teacher,见以下代码:
package com.example.demo.entity;import lombok.Data;
import org.hibernate.annotations.Proxy;
import javax.persistence.*;@Data
@Entity
public class Teacher {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private long id;private String name;@ManyToOneprivate School school;
}
2.测试映射关系
Service 和 Repository 层在《关系映射开发(一):一对一映射》已经讲过,这里并没有区别,所以不再赘述。
下面直接测试一对多的关系映射。在测试类中,写入以下代码:
package com.example.demo.entity;import com.example.demo.repository.SchoolRepository;
import com.example.demo.repository.TeacherRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.util.List;@SpringBootTest
@RunWith(SpringRunner.class)
public class OneToManyTest {@Autowiredprivate SchoolRepository schoolRepository;@Autowiredprivate TeacherRepository teacherRepository;@Testpublic void add() {School school1 = new School();school1.setName("清华大学");schoolRepository.save(school1);Teacher teacher = new Teacher();teacher.setName("long");teacher.setSchool(school1);teacherRepository.save(teacher);}@Testpublic void find() {School school1 = new School();school1 = schoolRepository.findSchoolById(1);List<Teacher> teacherList = school1.getTeacherList();System.out.println(school1.getName());for (Teacher teacher : teacherList) {System.out.println(teacher.getName());}}@Testpublic void deleteSchoolById() {schoolRepository.deleteById(3);}@Testpublic void deleteTeacherById() {teacherRepository.deleteById(7);}
}
运行测试 add
方法,在控制台输出如下结果:
运行测试 find
方法,在控制台输出如下结果:
运行测试 deleteSchoolById 方法,在控制台输出如下结果:
可以看到,先将所有 Teacher 表的外键设置为空,然后删除 School 表的指定值。
运行测试 deleteTeacherByld 方法,在控制台输岀如下结果:
可见是直接删除指定 Teacher 表的值,并没有删除 School 表的数据。
🚀 在双向一对多关系中:
- 注解
@OneToMany(mappedBy='发出端实体名称小写')
用于关系的 发出端(即 One 的一方),同时关系的发出端需要定义一个集合类型的接收端的字段属性。- 注解
@ManyToOne
用于关系的 接收端(即 Many 的一方),关系的接收端需要定义一个发出端的字段属性。