Hibernate中的cascade、inverse以及mappedBy用法

    学习hibernate时对级联关系的概念老是分不清楚,尤其是cascade、inverse以及mappedBy的作用。下面通过例子来简单说明。

准备工作

    首先创建数据库,新建两张表:

   教室表cr,字段如下


    学生表student,字段如下:


   教室与学生是一对多的关系。

    然后新建项目,添加hibernate支持,由于inverse是hbm.xml配置文件中的属性,而mappedBy是注解中的属性,因此分开说明。

cascade属性

    cascade用于指示级联关系,即两个实体间存在级联关系(一个类是另一个类中的属性)时,当保存、更新或删除一个实体时,是否对关联的实体做出相应操作(数据库操作),例如

<hibernate-mapping>
    <class name="model.Cr" table="cr" catalog="hbmtest">
        <id name="id" type="integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <property name="cname" type="string">
            <column name="cname" length="20" />
        </property>
        <set name="students" inverse="true">
            <key>
                <column name="crid" />
            </key>
            <one-to-many class="model.Student" />
        </set>
    </class>
</hibernate-mapping>

上面是cr表的映射配置,执行如下测试代码

        Session session = HibernateSessionFactory.getSession();
        session.beginTransaction();
        Student stu = new Student();
        stu.setName("zhu");
        Cr cr = new Cr();
        cr.setCname("cname");
        Set<Student> set = new HashSet<Student>();
        set.add(stu);
        cr.setStudents(set);
        stu.setCr(cr);
        session.save(cr);
        session.getTransaction().commit();

执行上面代码后,数据表cr中插入一行,而student表未变化上面的配置改为

<set name="students" cascade="all" inverse="true">后,执行上述代码则student表会有数据插入。

inverse

    inverse属性用于指示本方是否参与维护关系,设为true时不维护,设为false时维护。此处的关系是指关联两张表的

外键或者关系表字段。本属性一般设置于一对多关系中的一端,并且设置为false,因为若由一端负责维护,每次更一端数据,都会去寻找于一端有关系的多段表中的行,并更新其外键字段。而由多端维护时,由于一端对象是多端对象的属性字段,所以,每次更新多端后提交数据,都会自动更新该字段(若有更新时),这样比较方便

<hibernate-mapping>
    <class name="model.Cr" table="cr" catalog="hbmtest">
        <id name="id" type="integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <property name="cname" type="string">
            <column name="cname" length="20" />
        </property>
        <set name="students" cascade="all" inverse="true">
            <key>
                <column name="crid" />
            </key>
            <one-to-many class="model.Student" />
        </set>
    </class>
</hibernate-mapping>

执行以下测试代码:   
                Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();
		Student stu = new Student();
		stu.setName("zhu");
		Cr cr = new Cr();
		cr.setCname("cname");
		Set<Student> set = new HashSet<Student>();
		set.add(stu);
		cr.setStudents(set);
		session.save(cr);
		session.getTransaction().commit();
结果

cr

student表

由上图可以看出,由于cr不负责维护关系,所以插入一条cr数据后虽然在student插入一行,但其外键为null。当更改inverse为false或默认设置时,结果会更新student表的crid字段。

mappedBy

    mappedBy属性用于注解中,作用与inverse类似,不过其值必须为多端对象中对应一端对象的成员变量名。当设置后,由多端维护关系,未设置时,hibernate会去寻找由student的id字段和cr的id字段组成的关系表,如果未建立该表会报错。为了避免报错并且由两端同时维护关系,可以在一端加上@JoinColumn(name="多端外键字段名"),这样作用就等同于inverse=false了。

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
	@JoinColumn(name="crid")
	public Set<Student> getStudents() {
		return this.students;
	}

		Session session = HibernateSessionFactory.getSession();
		session.beginTransaction();
		Student stu = new Student();
		stu.setName("zhu");
		Cr cr = new Cr();
		cr.setCname("cname");
		Set<Student> set = new HashSet<Student>();
		set.add(stu);
		cr.setStudents(set);
		session.save(cr);
		session.getTransaction().commit();

执行结果未两张表均插入一行,而且student表中的外键不为空。



如果您觉得这文章对您有帮助,可以打赏点钱给我,鼓励我继续写博,我的支付宝


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值