Hibernate 级联学习

场景描述

班级与学生一对多,一个班级中有多个学生,

clipboard.png

我们只希望操作班级,而将学生的一些操作直接级联到数据库。

示例

实体

@Entity
public class Klass {

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

    private String name;

    @OneToMany(mappedBy = "klass")
    private Set<Student> studentSet = new HashSet<>();
}
@Entity
public class Student {

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

    private String name;

    @ManyToOne
    private Klass klass;
}

不级联

@Test
public void test() {

    Klass klass = new Klass();
    klass.setName("测试班级");

    Student student1 = new Student();
    Student student2 = new Student();

    student1.setName("测试学生1");
    student2.setName("测试学生2");

    klass.setStudentSet(new HashSet<>(Arrays.asList(student1, student2)));

    klassRepository.save(klass);
}

班级表:

clipboard.png

学生表:

clipboard.png

PERSIST

@OneToMany(mappedBy = "klass", cascade = CascadeType.PERSIST)
private Set<Student> studentSet = new HashSet<>();

班级表:

clipboard.png

学生表:

clipboard.png

学生已经级联保存,但是学生的klass_id却是空,可见级联是直接将set中的对象持久化到数据库,而未对其ManyToOne的关系进行维护。我们需要手动维护多对一的关系。

@Test
public void test() {

    Klass klass = new Klass();

    klass.setName("测试班级");

    Student student1 = new Student();
    Student student2 = new Student();

    student1.setName("测试学生1");
    student2.setName("测试学生2");

    student1.setKlass(klass);
    student2.setKlass(klass);

    klass.setStudentSet(new HashSet<>(Arrays.asList(student1, student2)));

    klassRepository.save(klass);
}

班级表:

clipboard.png

学生表:

clipboard.png

MERGE

@OneToMany(mappedBy = "klass", cascade = {CascadeType.PERSIST, CascadeType.MERGE})
private Set<Student> studentSet = new HashSet<>();

官方文档:CascadeType.MERGE

@Test
public void test() {
    Klass klass = klassRepository.findOne(1L);
    for (Student student : klass.getStudentSet()) {
        student.setName("修改后的学生");
    }
    klassRepository.save(klass);
}

clipboard.png

During merge, the current state of the entity is copied onto the entity version that was just fetched from the database. That’s the reason why Hibernate executed the SELECT statement which fetched both the Person entity along with its children.

MERGE期间,实体的当前状态被复制到刚刚从数据库中取出的实体版本。这就是为什么Hibernate执行SELECT语句,既能获取Person实体,又能获取它的子实体。

REMOVE

OneToMany的级联加上属性CascadeType.REMOVE

删除就简单了,我们直接测试删除掉id1的班级,此时数据库设置为update

@Test
public void test() {
    klassRepository.delete((long) 1);
}

clipboard.png

clipboard.png

班级表该条记录删除,同时学生表中的记录也被级联删除。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值