hibernate注解:多对多双向

本次实验环境:spring boot + spring data jpa + hibernate

本次实验用例:
  学生:
      id
      name
      teachers
  教师:
      id
      nr
      students

本次实例展示如何编写多对多双向关系,直接展示常用的编写方式,不再涉及假设讨论。

#Teacher类:
@Entity
@Table(name="t_n2n_teacher")
public class Teacher {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @ManyToMany
    @JoinTable(name="t_teacher_student", joinColumns=@JoinColumn(name="teacher_id"), inverseJoinColumns=@JoinColumn(name="student_id"))
    private List<Student> students;

    //getter与setter省略
}

@JoinTable设置中间表,name为中间表名,joinColumns为本类在中间表中的字段,inverseJoinColumns为另一方在中间表中的字段。

#Student类:
@Entity
@Table(name="t_n2n_student")
public class Student {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    @ManyToMany
    @JoinTable(name="t_teacher_student", joinColumns=@JoinColumn(name="student_id"), inverseJoinColumns=@JoinColumn(name="teacher_id"))
    private List<Teacher> teachers;

    //getter与setter省略
}
#生成表

这里写图片描述
这里写图片描述
这里写图片描述


CRUD:
  • 添加teacher,直接添加即可。
    Teacher teacher = new Teacher();
    teacher.setName("李老师");
    teacherDao.saveAndFlush(teacher);
  • 更新teacher,先查出原有数据再更新。
    Teacher teacher = teacherDao.findOne(1L);
    teacher.setName("李教授");
    teacherDao.saveAndFlush(teacher);
  • 删除teacher,级联删除中间表对应数据。
    teacherDao.delete(1L);
  • 查询teacher,@ManyToMany默认为懒加载。
    Teacher findOne = teacherDao.findOne(1L);
    System.err.println(findOne.getName());

  • 添加student,直接添加。
    Student student = new Student();
    student.setName("小红");
    studentDao.saveAndFlush(student);

  • 更新student,先查出原有数据再更新。
    Student student = studentDao.findOne(1L);
    student.setName("大明");
    studentDao.saveAndFlush(student);
  • 删除student,级联删除中间表对应数据。
    studentDao.delete(1L);;
  • 查询student,@ManyToMany默认烂加载。
    Student findOne = studentDao.findOne(1L);
    System.err.println(findOne.getName());

  • 添加student和teacher关系,不管从student方还是teacher方都能设置,但是得保证在同一个session中
    @Transactional
    public void teach() {
    Teacher teacher = teacherDao.findOne(1L);
    Student student = studentDao.findOne(1L);
    List<Student> students = teacher.getStudents();
    students.add(student);
    teacherDao.saveAndFlush(teacher);
    }


    @Transactional
    public void learn() {
    Student student = studentDao.findOne(1L);
    Teacher teacher = teacherDao.findOne(1L);
    List<Teacher> teachers = student.getTeachers();
    teachers.add(teacher);
    studentDao.saveAndFlush(student);
    }

  • 删除关系,即删除中间表的数据,建议直接通过原生的sql实现。
    @Modifying
    @Transactional
    @Query(nativeQuery=true, value="delete from t_teacher_student where teacher_id=?1 and student_id=?2")
    public int notTeach(Long teacherId, Long studentId);


    @Modifying
    @Transactional
    @Query(nativeQuery=true, value="delete from t_teacher_student where teacher_id=?1 and student_id=?2")
    public int notLearn(Long teacherId, Long studentId);

    notTeach方法定义在TeacherDao中,notLearn方法定义在StudentDao中,不管通过哪一方都能删除。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值