9、Spring Data JPA 之 表与表关系建立(多对多)
多对多
有两个实体类,Teacher 和 Student,它们之间存在多对多的关系
实体类
Student
@Entity
@Table(name = "t_student")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "student_id")
private Integer studentId;
@Column(name = "s_name")
private String name;
@Column(name = "s_gender")
private String gender;
/**
* mappedBy 对方配置映射关系的属性名称
*/
@ManyToMany(mappedBy = "students", cascade = CascadeType.ALL)
private List<Teacher> teachers = new ArrayList<>();
public List<Teacher> getTeachers() {
return teachers;
}
public void setTeachers(List<Teacher> teachers) {
this.teachers = teachers;
}
public Integer getStudentId() {
return studentId;
}
public void setStudentId(Integer studentId) {
this.studentId = studentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student{" +
"studentId=" + studentId +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
'}';
}
}
Teacher
@Entity
@Table(name="t_teacher")
public class Teacher {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "emp_id")
private Integer empId;
@Column(name = "t_name")
private String name;
@ManyToMany(targetEntity = Student.class, cascade = CascadeType.ALL)
@JoinTable(name = "tb_teacher_student",
//joinColumns,当前对象在中间表中的外键
joinColumns = {@JoinColumn(name = "tb_teacher_id", referencedColumnName = "emp_id")},
//inverseJoinColumns 对方对象在中间表的外键
inverseJoinColumns = {@JoinColumn(name = "tb_student_id", referencedColumnName = "student_id")}
)
private List<Student> students = new ArrayList<>();
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Teacher{" +
"empId=" + empId +
", name='" + name + '\'' +
'}';
}
}
接口
StudentDao
/**
* 符合Spring Data Jpa 的 dao层接口规范
* JpaRepository<操作的实体类类型,实体类中主键属性的类型>
* #封装了基本CRUD操作
* JpaSpecificationExecutor <操作的实体类类型>
* #封装了复杂查询(分页)
*/
public interface StudentDao extends JpaRepository<Student, Integer>,JpaSpecificationExecutor<Student>{
}
TeacherDao
/**
* 符合Spring Data Jpa 的 dao层接口规范
* JpaRepository<操作的实体类类型,实体类中主键属性的类型>
* #封装了基本CRUD操作
* JpaSpecificationExecutor <操作的实体类类型>
* #封装了复杂查询(分页)
*/
public interface TeacherDao extends JpaRepository<Teacher, Integer>,JpaSpecificationExecutor<Teacher>{
}
测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")//指定spring容器的配置信息
public class ManyToManyTest {
@Autowired
private TeacherDao teacherDao;
@Autowired
private StudentDao studentDao;
/**
* 级联添加
*/
@Test
@Transactional
@Rollback(false)
public void testAdd(){
Teacher teacher = new Teacher();
teacher.setName("林老师");
Student student = new Student();
student.setName("小黑");
student.setGender("男");
/**
* 当两方都拥有维护中间表的权力时,中间表的联合主键会重复出现两次或报错
* 这时有有一方就需要放弃维护权
*/
//配置用户到角色关系,可以贵中间表中的数据进行维护
teacher.getStudents().add(student);
//配置角色到用户的关系,可以对中间表的数据进行维护
student.getTeachers().add(teacher);
teacherDao.save(teacher);
}
/**
* 级联删除
*/
@Test
@Transactional
@Rollback(false)
public void testRemove(){
//查询1号用户
Student student = studentDao.findOne(1);
System.out.println(student);
//删除1号用户
studentDao.delete(student);
}
}