HIbernate级联操作cascade以及inverse管理关系
2017-07-17 11:03
363 查看
一、cascade级联
cascade叫级联,有了级联可以使我们在操作(增删改查)数据时,避免因为各种各样的原因,丢掉向关联的数据库,下面先把cascade的总结写一下总结:
1、cascade时级联操作,使得在操作一端数据时,可以级联操作被关联的另外一端的数据。
2、在多对一的关系中,多的一端不能操作级联为delete。一般在多的一端设为save-update;
3、在一对多的关系中,如果一的一端设置为delete时,多的一端不能指明外键为空。
新建一个项目,名叫11hibernate_cascade,结构如下:
项目中用的jar包以及如何从hibernate官网获取,请参见《Hibernate环境搭建和配置》
实体类Grade的配置文件Grade.hbm.xml代码如下:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.robert.pojo"> <class name="Grade"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <!-- set:Grade类中的集合属性 name:属性名称 --> <set name="students"> <!-- key:外键; column:外键列名; --> <key column="grade_id"/> <!-- ont-to-many:一对多,类Grade中students所表示的类型 --> <one-to-many class="Student"/> </set> </class> </hibernate-mapping>
实体类Student的配置文件Student.hbm.xml代码如下:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.robert.pojo"> <class name="Student"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <property name="age"></property> <!-- cascade:级联,让操作级联到子实体,常用属性如下: save-update:保存和更新多的一端的数据时,一的一端的数据,可以一起保存和更新 ; none:不级联,默认就是none; delete:删除级联(从多的一端删除一的一端的数据,不符合,不能在多的一端使用); all:所有操作都级联; --> <many-to-one name="grade" class="Grade" column="grade_id" cascade="save-update" not-null="true" /> </class> </hibernate-mapping>
实体类Grade和Student、工具类HibernateUtil、hibernate.cfg.xml配置文件请参见《Hibernate单向一对多映射和双向一对多映射》
HibernateTest类的代码如下:
package com.robert.test; import java.io.IOException; import java.sql.SQLException; import java.util.Iterator; import javax.sql.rowset.serial.SerialException; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.junit.Test; import com.robert.pojo.Grade; import com.robert.pojo.Student; import com.robert.util.HibernateUtil; public class HibernateTest { /** * 根据*.hbm.xml文件对应的生成数据库表 */ @Test public void testCreateDB() { Configuration cfg = new Configuration().configure(); SchemaExport se = new SchemaExport(cfg); // 第一个参数:是否生成ddl脚本 // 第二个参数:是否执行到数据库中 se.create(true, true); } /** * 保存数据 * @throws HibernateException * @throws SerialException * @throws SQLException * @throws IOException */ @Test public void testSave() throws HibernateException, SerialException, SQLException, IOException { Session session = null; Transaction tx = null; try { session = HibernateUtil.getSession(); tx = session.beginTransaction(); Grade grade = new Grade(); grade.setName("基础") ; Student student = new Student() ; student.setName("张三") ; student.setAge(22) ; student.setGrade(grade) ;//关联关系由多的一端维护 Student student2 = new Student() ; student2.setName("李四") ; student2.setAge(23) ; student2.setGrade(grade) ;//关联关系由多的一端维护 //因为在Student.hbm.xml配置文件中的<many-to-one>标签中,是使用了cascade属性,所以可以不用save(grade), // 当执行到save(student)时,程序发现没有grade,会自动执行save(grade) // session.save(grade); session.save(student) ; session.save(student2); tx.commit(); } catch (HibernateException e) { if (tx != null) { tx.rollback(); } e.printStackTrace(); throw e; } finally { HibernateUtil.closeSession(); } } @Test public void testGet() { Session session = null ; Transaction tx = null ; try { session = HibernateUtil.getSession() ; tx = session.beginTransaction() ; //取数据 Grade grade = (Grade) session.get(Grade.class, 1) ; System.out.println("grade_name:"+grade.getName()); Iterator<Student> it = grade.getStudents().iterator() ; while (it.hasNext()) { Student student = (Student) it.next(); System.out.println("student_name:"+student.getName()); } tx.commit() ; } catch (Exception e) { tx.rollback(); e.printStackTrace(); }finally { HibernateUtil.closeSession() ; } } }
具体的演示步骤就不展示了,有兴趣的同学可以自己尝试一下。
=============================================================================
二、inverse管理关系
inverse用来指定由谁来管理关系,如果为false,则双方都可以管理关系;
如果为true,则关系由设置inverse的另一方来管理。
大部分代码和上面的代码相同,下面我把不同的代码贴出来
(a)Grade.hbm.xml代码:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.robert.pojo"> <class name="Grade"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <!-- set:Grade类中的集合属性 name:属性名称 --> <!-- inverse:设置由谁来管理关系; 如果为false,则双方都可以管理关系; 如果为true,则关系由设置inverse的另一方来管理 --> <set name="students" inverse="false"> <key column="grade_id" /> <!-- ont-to-many:一对多,类Grade中students所表示的类型 --> <one-to-many class="Student" /> </set> </class> </hibernate-mapping>
1)当inverse是false时,说明你关系有由双方都可以管理关系,
使用Junit4测试,运行成功
数据库数据如图:
2)运行testCreateDB,重新生成数据库表
由一的一端维护关系
console控制台,打印的sql语句是:
Hibernate: insert into Grade (name) values (?) Hibernate: insert into Student (name, age, grade_id) values (?, ?, ?) Hibernate: insert into Student (name, age, grade_id) values (?, ?, ?) Hibernate: update Student set grade_id=? where id=? Hibernate: update Student set grade_id=? where id=?
查看数据库表:
(b)Grade.hbm.xml代码如下(inverse=“true”):
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.robert.pojo"> <class name="Grade"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <!-- set:Grade类中的集合属性 name:属性名称 --> <!-- inverse:设置由谁来管理关系; 如果为false,则双方都可以管理关系; 如果为true,则关系由设置inverse的另一方来管理 --> <set name="students" inverse="true"> <key column="grade_id" /> <!-- ont-to-many:一对多,类Grade中students所表示的类型 --> <one-to-many class="Student" /> </set> </class> </hibernate-mapping>
此时我们是在Grade端即一端设置了inverse=“true”,那么关系应该由另一方来管理,就是说由多的一方Student端来管理,代码如下:
总结:
inverse设置关系维护方,当inverse=“false”时,谁管理关系谁维护,如果都管理了,那么就都维护。
当关系由多的一端来维护时,效率较高;
当关系由一的一端来维护时,会多执行update语句。
相关文章推荐
- hibernate里inverse与cascade标签的作用以及区别
- inverse和cascade的区别,以及一对多添加操作时外键为Null的问题
- 【JavaWeb-20】3种对象状态以及相互转化、一级缓存和快照、Session其他API、一对多配置和操作、cascade
- Hibernate级联操作和加载机制(二) cascade and fetch
- Hibernate中的cascade、inverse以及mappedBy用法 .
- 06章 映射一对多双向关联关系、以及cascade、inverse属性
- Hibernate中的双向多对一关联以及 inverse属性、cascade属性的用法
- hibernate级联(cascade和inverse) .
- 06章 映射一对多双向关联关系、以及cascade、inverse属性
- 06章 映射一对多双向关联关系、以及cascade、inverse属性
- 第33天(就业班) 关联映射、集合映射、一对多映射、inverse属性、cascade级联操作、多对多映射配置
- hibernate中关系操作(inverse)和级联操作(cascade)详解
- hibernate笔记--cascade级联以及inverse属性
- Hibernate 级联操作cascade及inverse
- Hibernte之级联操作inverse、cascade
- Inverse属性和cascade属性以及集合的多对多关系
- SVN建立分支、代码合并以及常用操作
- Hibernate映射中的Inverse和cascade
- php数据库操作-创建库和表以及插入数据
- 用jquery实现cookie的操作以及创建js数组和遍历js数组,js对象,jquery.json的使用