Hibernate中的cascade、inverse以及mappedBy用法 .

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

准备工作

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

   教室表cr,字段如下


    学生表student,字段如下:


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

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

cascade属性

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

  1. <SPAN style="FONT-SIZE: 18px"><hibernate-mapping>  
  2.     <class name="model.Cr" table="cr" catalog="hbmtest">  
  3.         <id name="id" type="integer">  
  4.             <column name="id" />  
  5.             <generator class="identity" />  
  6.         </id>  
  7.         <property name="cname" type="string">  
  8.             <column name="cname" length="20" />  
  9.         </property>  
  10.         <set name="students" inverse="true">  
  11.             <key>  
  12.                 <column name="crid" />  
  13.             </key>  
  14.             <one-to-many class="model.Student" />  
  15.         </set>  
  16.     </class>  
  17. </hibernate-mapping></SPAN>  
<span style="FONT-SIZE: 18px"><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></span>

上面是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表未变化上面的配置改为

  1. <SPAN style="FONT-SIZE: 18px"><set name="students" cascade=<SPAN style="FONT-SIZE: 18px">"all" </SPAN>inverse="true">后,执行上述代码则<SPAN style="FONT-SIZE: 18px">student表会有<SPAN style="FONT-SIZE: 18px">数据插入。  
  2. </SPAN></SPAN></SPAN>  
<span style="FONT-SIZE: 18px"><set name="students" cascade=<span style="FONT-SIZE: 18px">"all" </span>inverse="true">后,执行上述代码则<span style="FONT-SIZE: 18px">student表会有<span style="FONT-SIZE: 18px">数据插入。
</span></span></span>

inverse

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

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

  1. <hibernate-mapping>  
  2.     <class name="model.Cr" table="cr" catalog="hbmtest">  
  3.         <id name="id" type="integer">  
  4.             <column name="id" />  
  5.             <generator class="identity" />  
  6.         </id>  
  7.         <property name="cname" type="string">  
  8.             <column name="cname" length="20" />  
  9.         </property>  
  10.         <set name="students" cascade="all" inverse="true">  
  11.             <key>  
  12.                 <column name="crid" />  
  13.             </key>  
  14.             <one-to-many class="model.Student" />  
  15.         </set>  
  16.     </class>  
  17. </hibernate-mapping>  
<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>

执行以下测试代码:   
  1.               Session session = HibernateSessionFactory.getSession();  
  2. session.beginTransaction();  
  3. Student stu = new Student();  
  4. stu.setName("zhu");  
  5. Cr cr = new Cr();  
  6. cr.setCname("cname");  
  7. Set<Student> set = new HashSet<Student>();  
  8. set.add(stu);  
  9. cr.setStudents(set);  
  10. session.save(cr);  
  11. session.getTransaction().commit();  
                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了。

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

  1. Session session = HibernateSessionFactory.getSession();  
  2. session.beginTransaction();  
  3. Student stu = new Student();  
  4. stu.setName("zhu");  
  5. Cr cr = new Cr();  
  6. cr.setCname("cname");  
  7. Set<Student> set = new HashSet<Student>();  
  8. set.add(stu);  
  9. cr.setStudents(set);  
  10. session.save(cr);  
  11. session.getTransaction().commit();  
		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表中的外键不为空。


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值