cascade和inverse

本文详细解释了数据库中级联操作(增删改)和外键维护的概念,通过实例展示了如何使用inverse属性控制关系表的维护权,并介绍了cascade属性在不同场景下的作用。同时,阐述了数据库操作时的性能考量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        cascade理解起来比较简单就是级联操作(增删改),inverse不是很好理解网上查的资料都是说维护关系用的,这个单词的意思是inverse是“逆,对面的”也就是反过来,inverse=true就是另一方维护的意思,反之就是自己维护,不知道有木有理解错误。。。。网上所说的维护关系,就是维护外键的值。

          举个例子吧,有两张表:学校表school和学生表student,一对多的关系,代码和配置文件如下:

public class Student implements Serializable {
	private String id;
	private String name;
	private School school;
}

     

<many-to-one name="school" class="com.bean.School" fetch="join">
	<column name="SCHOOL_ID" />
</many-to-one>

 

public class School {
	private String id;
	private String name;
	private Set<Student> students = new HashSet<Student>(0);
        //添加学生
        public void addStudent(Student s){
		students.add(s);
	}
} 

   

//inverse="true"说明让另一方(即STUDENT)来维护STUDENT表中的外键,注意这里的inverse是指Scho//ol,因为这个是School表,这就意味着school不是主控方(主控方才会维护外键关系),不会维护STUDENT表的SCHOOL_ID字段
<set name="students" table="STUDENT" inverse="true" lazy="true"     cascade="all-delete-orphan">
		<key>
			<column name="SCHOOL_ID" />
	      </key>
	<one-to-many class="com.bean.Student" />
</set>

    测试代码如下:

	School school = new School();
	school.setName("某某高校");
	Student s1=  new Student();
	s1.setName("学生1");
	school.addStudent(s1);
	Student s2=  new Student();
	s2.setName("学生2");
	school.addStudent(s2);
	session.save(school);

   运行结果:

 

  Hibernate: insert into SCHOOL (NAME, ID) values (?, ?)

  Hibernate: insert into STUDENT (NAME, SCHOOL_ID, ID) values (?, ?, ?)

  Hibernate: insert into STUDENT (NAME, SCHOOL_ID, ID) values (?, ?, ?)

   发送了3条SQL,再来看看数据库STUDENT表的记录

   SCHOOL_ID 没有值,因为外键关系school已经不管了,需要student维护,修改测试代码:

    School school = new School();
    school.setName("某某高校");
    Student s1=  new Student();
    s1.setName("学生1");
    school.addStudent(s1);
    Student s2=  new Student();
    s2.setName("学生2");
    school.addStudent(s2);
    s1.setSchool(school);
    s2.setSchool(school);
    session.save(school);

   运行结果:

 

  Hibernate: insert into SCHOOL (NAME, ID) values (?, ?)

  Hibernate: insert into STUDENT (NAME, SCHOOL_ID, ID) values (?, ?, ?)

  Hibernate: insert into STUDENT (NAME, SCHOOL_ID, ID) values (?, ?, ?)

   也是发送了3条SQL,再来看看数据库STUDENT表的记录


 结果说明设置inverse=“true”需要student执行setSchool方法来自己维护外键的关系,如果想让school来维护外键关系,则需要设置inverse=“false”,配置文件如下:

<set name="students" table="STUDENT" inverse="false" lazy="true" cascade="all-delete-orphan">
	<key>
		<column name="SCHOOL_ID" />
	</key>
	<one-to-many class="com.bean.Student" />
</set>

  测试代码: 

  

			School school = new School();
			school.setName("某某高校");
			Student s1=  new Student();
			s1.setName("学生1");
			school.addStudent(s1);
			Student s2=  new Student();
			s2.setName("学生2");
			school.addStudent(s2);
                       //s1.setSchool(school);
                       //s2.setSchool(school);
			session.save(school);

   运行结果:

   Hibernate: insert into SCHOOL (NAME, ID) values (?, ?)

Hibernate: insert into STUDENT (NAME, SCHOOL_ID, ID) values (?, ?, ?)

Hibernate: insert into STUDENT (NAME, SCHOOL_ID, ID) values (?, ?, ?)

Hibernate: update STUDENT set SCHOOL_ID=? where ID=?

Hibernate: update STUDENT set SCHOOL_ID=? where ID=?

 额外执行了两次update,说明school维护了外键关系,两次update就是更新外键的,在看看数据库student表:


cascade有四种取值:

        none: 默认值,任何情况都不进行关联操作。 

            save-update: 在执行save/update/saveOrUpdate时进行关联操作。            

          delete: 在执行delete 时进行关联操作。

        all: 所有情况下均进行关联操作,即save-update和delete。

 

       all-delete-orphan: 当一个节点成为孤儿节点时,删除该节点。

 这里说明一下设置cascade="all-delete-orphan",就是在执行

school.getStudents().remove(student);
student.setSchool(null);

  student就成了孤儿节点了,那么hibernate在同步缓存到数据库时就会把对应的记录删除了。

ps:orphan就是孤儿的意思,英语不好伤不起。。。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值