Hibernate的inverse,cascade属性简单介绍

本篇博客将在上篇双向一对多的情况下介绍inverse,cascade属性的作用

inverse(反转)

inverse:指定关联关系的控制方向,默认由one方来维护。在关联关系中,inverse="false"则为主动方,由主动方负责维护关联关系。在一对多关联中,只能设置one方的inverse为true,这将有助于性能的改善。

我先将我的Classes.hbm.xml代码贴出来,(注意:在这里我们配置的是双向的一对多的配置方法,其他的配置请看我的上篇博客)

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-8-13 10:41:54 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.yc.entity.Classes" table="CLASSES">
        <id name="cid" type="int">
            <column name="CID" />
            <generator class="sequence" >
            	<param name="sequence">seq_classes_cid</param>
            </generator>
        </id>
        <property name="cname" type="java.lang.String">
            <column name="CNAME" />
        </property>
        <set name="students" table="STUDENT" inverse="false" lazy="true">
            <key>
                <column name="CID" />
            </key>
            <one-to-many class="com.yc.entity.Student" />
        </set>
    </class>
</hibernate-mapping>

便于之后的解说我将测试代码也贴出来

package com.yc.test;

import java.util.Collections;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import com.yc.entity.Classes;
import com.yc.entity.Student;
import com.yc.utils.HibernateUtil;

//测试双向一对多
public class MyTest3 {
	@Test
	//测试多对一
	public void testSave(){
		Classes c=new Classes("大唐官府");

		Student s1=new Student("剑侠客");
		Student s2=new Student("飞燕女");

		//设置关联关系
		Collections.addAll(c.getStudents(), s1,s2);
		s1.setCid(c);
		s2.setCid(c);

		Session session=HibernateUtil.getSession();
		Transaction tx=session.beginTransaction();

		session.save(c);
		session.save(s1);
		session.save(s2);

		tx.commit();
		HibernateUtil.closeSession(session);
	}
}

OK,在这里我们可以看见在hbm文件的set标签中的inverse为false,这会出现什么问题呢?我们不妨运行一下测试代码,来看看控制台的信息


哇,我们发现了啥,对于已经填写完成的学生信息,为什么会多出俩update的操作?

在这里是因为我们将inverse设置为false,那么他们的关联关系就交给了one的一方去控制,所以我们在执行的时候还会执行俩条update的sql语句。

好了,到这里,我们会发现,这俩条update语句没作用啊,放在这里碍眼不说还影响了性能,怎么把它干掉呢?我们来试试将inverse设置为true。

        <set name="students" table="STUDENT" inverse="true" lazy="true">
        	<!-- 指定关联的外键列 -->
            <key>
                <column name="CID" />
            </key>
            <one-to-many class="com.yc.test3.Student3" />
        </set>
再次执行我们的测试方法

yes,成功的执行并且解决掉了碍眼的update操作奋斗


cascade(级联)

cascade级联属性设置不为none时,hibernate会自动持久化所关联对象:all、save-update、delete、none

细心的小伙伴会发现在测试方法中我已经将学生信息保存在班级信息中了,为什么还要再用session去save一下啊,这不重复了吗?

OK,对于这个问题,发现的很好,就是我们的cascade属性啦,同样我们在hbm文件中加入我们的cascade属性来测试一下

        <set name="students" table="STUDENT" inverse="true" lazy="true" cascade="save-update">
        	<!-- 指定关联的外键列 -->
            <key>
                <column name="CID" />
            </key>
            <one-to-many class="com.yc.entity.Student" />
        </set>
再来修改我们的测试方法

	@Test
	public void testSave(){
		Classes c=new Classes("大唐官府");

		Student s1=new Student("剑侠客");
		Student s2=new Student("飞燕女");

		//设置关联关系
		Collections.addAll(c.getStudents(), s1,s2);
		s1.setCid(c);
		s2.setCid(c);

		Session session=HibernateUtil.getSession();
		Transaction tx=session.beginTransaction();

		session.save(c); //级联操作
		//session.save(s1); //注意这俩行是注释掉的
		//session.save(s2);

		tx.commit();

		HibernateUtil.closeSession(session);
	}

执行


JUnit通过,说明我们的cascade属性起到了作用,级联成功。当然如果你想通过保存学生来保存班级的信息,一个道理只需在student的hbm文件设置cascade即可。

在这里我简单的介绍一下cascade的四个属性

1.save-update:在保存以及更新的时候进行级联操作
2.delete:最删除操作进行级联操作
3.all:对所有的操作进行级联操作
4.none:对所有的操作不进行级联操作

发布了36 篇原创文章 · 获赞 4 · 访问量 6万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章