JPA之ManyToMany示例


3个月前 166次点击 来自 后端

标签: JPA

四个实体类:学生, 教室,老师,课桌

  • 一个学生通常只有一个课桌,一个课桌通常给一个学生作,这里学生和课桌的关系就是互为 @OneToOne
  • 一个教室通常可以容纳很多的学生,教室到学生的关系就可以定义为 @OneToMany
  • 很多学生容纳在一个教室当中,学生到教室的关系可以定义为 @ManyToOne
  • 一个学生可以有很多的老师,一个老师可以有很多的学生,这里学生和老师的关系就互为 @ManyToMany

ManyToMany

Teacher.java

@Entity
@Getter
@Setter
@Table(name = "t_teacher")
public class Teacher {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private String subject;

    @ManyToMany(mappedBy = "teachers")
    private Set<Student> students;
}

Student.java

@Entity
@Getter
@Setter
@Table(name = "t_stu")
public class Student {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(length = 100)
    private String name;

    private Integer age;

    /**
     * 定义学生与课桌 一对一
     * JoinTable用于生成中间表 stu_desk 维护学生与课桌的关系 ,如果没有使用JoinTable则会在 stu 表中生成一个指向 desk 的外键 desk_id 用来维护关系
     * CascadeType.PERSIST 指定级联保存
     */
    @OneToOne(cascade = {CascadeType.PERSIST})
    @JoinTable(name = "t_stu_desk", joinColumns = @JoinColumn(name = "stu_id"), inverseJoinColumns = @JoinColumn(name = "desk_id"))
    private Desk desk;

    @Transient
    private String test;

    /**
     * 一对多和多对一的关系维护中,通常在多的一方进行外键的维护,运行程序我们会发现在 stu 表中新增了一个 classroom_id 的外键
     */
    @ManyToOne
    private Classroom classroom;


    @ManyToMany
    @JoinTable(name="t_stu_teacher",joinColumns = @JoinColumn(name ="stu_id"),inverseJoinColumns = @JoinColumn(name="teacher_id"))
    private Set<Teacher> teachers;
}

测试

Test 1 新增一条Teacher数据

@Test
void testSave() {
    Teacher teacher = new Teacher();
    teacher.setName("唐僧");
    teacher.setSubject("中文");
    teacherRepository.save(teacher);
}

Test 2 插入数据

@Test
@Transactional
@Rollback(false)
void testUpdateByTeacher(){
    Teacher teacher = teacherRepository.getById(1L);
    Student student = studentRepository.getById(1L);
    teacher.getStudents().add(student);
    teacherRepository.save(teacher);
}

查看SQL发现未能插入数据

Hibernate: select teacher0_.id as id1_30_0_, teacher0_.name as name2_30_0_, teacher0_.subject as subject3_30_0_ from t_teacher teacher0_ where teacher0_.id=?
Hibernate: select students0_.teacher_id as teacher_2_29_0_, students0_.stu_id as stu_id1_29_0_, student1_.id as id1_27_1_, student1_.age as age2_27_1_, student1_.classroom_id as classroo4_27_1_, student1_.name as name3_27_1_, student1_1_.desk_id as desk_id1_28_1_, classroom2_.id as id1_25_2_, classroom2_.name as name2_25_2_, desk3_.id as id1_26_3_, desk3_.number as number2_26_3_, desk3_1_.stu_id as stu_id0_28_3_, student4_.id as id1_27_4_, student4_.age as age2_27_4_, student4_.classroom_id as classroo4_27_4_, student4_.name as name3_27_4_, student4_1_.desk_id as desk_id1_28_4_ from t_stu_teacher students0_ inner join t_stu student1_ on students0_.stu_id=student1_.id left outer join t_stu_desk student1_1_ on student1_.id=student1_1_.stu_id left outer join t_classroom classroom2_ on student1_.classroom_id=classroom2_.id left outer join t_desk desk3_ on student1_1_.desk_id=desk3_.id left outer join t_stu_desk desk3_1_ on desk3_.id=desk3_1_.desk_id left outer join t_stu student4_ on desk3_1_.stu_id=student4_.id left outer join t_stu_desk student4_1_ on student4_.id=student4_1_.stu_id where students0_.teacher_id=?
Hibernate: select student0_.id as id1_27_0_, student0_.age as age2_27_0_, student0_.classroom_id as classroo4_27_0_, student0_.name as name3_27_0_, student0_1_.desk_id as desk_id1_28_0_, classroom1_.id as id1_25_1_, classroom1_.name as name2_25_1_, desk2_.id as id1_26_2_, desk2_.number as number2_26_2_, desk2_1_.stu_id as stu_id0_28_2_, student3_.id as id1_27_3_, student3_.age as age2_27_3_, student3_.classroom_id as classroo4_27_3_, student3_.name as name3_27_3_, student3_1_.desk_id as desk_id1_28_3_ from t_stu student0_ left outer join t_stu_desk student0_1_ on student0_.id=student0_1_.stu_id left outer join t_classroom classroom1_ on student0_.classroom_id=classroom1_.id left outer join t_desk desk2_ on student0_1_.desk_id=desk2_.id left outer join t_stu_desk desk2_1_ on desk2_.id=desk2_1_.desk_id left outer join t_stu student3_ on desk2_1_.stu_id=student3_.id left outer join t_stu_desk student3_1_ on student3_.id=student3_1_.stu_id where student0_.id=?

因为关系维护端在 Student 所有数据的更新与插入需要调用 studentRepository 完成

Test 3 插入数据

@Test
@Transactional
@Rollback(false)
void testUpdateByStudent(){
    Student student = studentRepository.getById(1L);
    Teacher teacher = teacherRepository.getById(1L);
    student.getTeachers().add(teacher);
    studentRepository.save(student);
}

SQL显示插入成功

Hibernate: select student0_.id as id1_27_0_, student0_.age as age2_27_0_, student0_.classroom_id as classroo4_27_0_, student0_.name as name3_27_0_, student0_1_.desk_id as desk_id1_28_0_, classroom1_.id as id1_25_1_, classroom1_.name as name2_25_1_, desk2_.id as id1_26_2_, desk2_.number as number2_26_2_, desk2_1_.stu_id as stu_id0_28_2_, student3_.id as id1_27_3_, student3_.age as age2_27_3_, student3_.classroom_id as classroo4_27_3_, student3_.name as name3_27_3_, student3_1_.desk_id as desk_id1_28_3_ from t_stu student0_ left outer join t_stu_desk student0_1_ on student0_.id=student0_1_.stu_id left outer join t_classroom classroom1_ on student0_.classroom_id=classroom1_.id left outer join t_desk desk2_ on student0_1_.desk_id=desk2_.id left outer join t_stu_desk desk2_1_ on desk2_.id=desk2_1_.desk_id left outer join t_stu student3_ on desk2_1_.stu_id=student3_.id left outer join t_stu_desk student3_1_ on student3_.id=student3_1_.stu_id where student0_.id=?
Hibernate: select teachers0_.stu_id as stu_id1_29_0_, teachers0_.teacher_id as teacher_2_29_0_, teacher1_.id as id1_30_1_, teacher1_.name as name2_30_1_, teacher1_.subject as subject3_30_1_ from t_stu_teacher teachers0_ inner join t_teacher teacher1_ on teachers0_.teacher_id=teacher1_.id where teachers0_.stu_id=?
Hibernate: select teacher0_.id as id1_30_0_, teacher0_.name as name2_30_0_, teacher0_.subject as subject3_30_0_ from t_teacher teacher0_ where teacher0_.id=?
Hibernate: insert into t_stu_teacher (stu_id, teacher_id) values (?, ?)

Made with in Shangrao,China By Devler.

Copyright © Devler 2012 - 2022

赣ICP备19009883号-1

Top ↑