Hibernate级联操作解密(inverse和cascade)

总结:

Cascade:对级联操作进行限制,有如下几个参数:

  all : 所有情况下均进行关联操作。 
  none:所有情况下均不进行关联操作。这是默认值。 
  save-update:在执行save/update/saveOrUpdate时进行关联操作。 
  delete:在执行delete时进行关联操作。

Inverse:在一对多模型中,只能在一的一方设置,inverse的作用就是在级联发生后,会再次更新子表数据的外键为主表的主键。确保子表外键不会为空。

下面演示一个班级学生的例子(一对多):

班级表javabean

public class Classes {

private Integer c_id;

private String c_name;

private String c_desc;

private Set<Student> student;

...}

班级表mapping

       .....其他字段省略,只写关联部分的代码

        <set name="student" table="STUDENT" cascade="save-update" inverse="false" lazy="true">

            <key>

                <column name="C_ID" />//此处对应子表外键约束名

            </key>

            <one-to-many class="com.cky.model.Student" />

        </set>

学生表bean如下

public class Student {

private Integer s_id;

private String s_name;

private Integer s_age;

private Classes cls;

....}

学生表mapping

        ...其他字段省略,只写关联部分的代码

        <many-to-one name="cls"  cascade="save-update" class="com.cky.model.Classes" fetch="join">

            <column name="C_ID" />//自己的外键约束名

        </many-to-one>

Classes Student是一对多关系,验证inverse作用

1、classesdescade=”save-update” inverse=”false”或者不写(默认false

执行如下操作:

Student st1=new Student("st1", 11);

Student st2=new Student("st2", 17);

Set<Student> stus=new HashSet<Student>();

stus.add(st1);

stus.add(st2);

//上面是创建两个学生对象,并添加到stus集合中

//下面是创建classes对象,并将学生集合传入

Classes cls=new Classes("班级1", "lal", stus);

ss.save(cls);

执行结果:注意最后的两个更新操作

Hibernate: select max(C_ID) from CLASSES

Hibernate: select max(S_ID) from STUDENT

Hibernate: insert into CLASSES (C_NAME, C_DESC, C_ID) values (?, ?, ?)

Hibernate: insert into STUDENT (S_NAME, S_AGE, C_ID, S_ID) values (?, ?, ?, ?)

Hibernate: insert into STUDENT (S_NAME, S_AGE, C_ID, S_ID) values (?, ?, ?, ?)

Hibernate: update STUDENT set C_ID=? where S_ID=?

Hibernate: update STUDENT set C_ID=? where S_ID=?

 

二、当classes descade=”save-update” inverse=”true”

执行结果:注意没有update了

Hibernate: select max(C_ID) from CLASSES

Hibernate: select max(S_ID) from STUDENT

Hibernate: insert into CLASSES (C_NAME, C_DESC, C_ID) values (?, ?, ?)

Hibernate: insert into STUDENT (S_NAME, S_AGE, C_ID, S_ID) values (?, ?, ?, ?)

Hibernate: insert into STUDENT (S_NAME, S_AGE, C_ID, S_ID) values (?, ?, ?, ?)

 

从结果可以看出来,当放弃维护关系的时候,少了两个更新语句

Inverse:是否放弃维护关系,就是是否对子表外键的进行额外更新操作,保证子表外键是自己的主键。

当级联发生时,有两种情况:

1、如果inversefalse,即classes选择维护关系的话。首先级联添加时会把Student对象的值插入表,由于需要维护关系,所以他会再次更新这些数据的外键关系。

将外键更新成自己的主键,这样他们一定有关系了。

2、如果inversetrue,即classes不维护关系,首先级联添加时会把Student对象的值插入表,但不会再次更新这些数据的外键关系,如果数据没有外键,就是空的,所以可以看到第二次执行中,由于我们创建Student对象时没有指定classes,所以添加后表中的结果也是null

总结:inverse只能在一的一方设置,inverse的作用就是在级联发生时,会再次更新子表数据的外键为主表的主键。确保子表外键不会为空。

正常情况都是将inverse设置成true来加快速度,子表数据的外键在创建子表对象时就设置好。

原文地址:https://www.cnblogs.com/chenkeyu/p/7395942.html