【7.3.1】级联操作--inverse

1. Inverse设置关系维护方。当inverse=”false”时,谁管理关系谁维护。如果都管理了,那么都维护。当关系由多的一端来维护时,效率较高。当关系由一的一端来维护时。会多执行update语句。

2.Inverse=”true”时,关系由另一端管理。不管一的一端是否指明关系,一的一端都不会去维护关系。都由多的一端负责。建议inverse=”true”.

3.Grade和Student类:

public class Grade {
	private int id;
	private String name;
	private Set<Student> students = new HashSet<Student>(0);
        /*省略get/set*/

 public class Student {
	private int id;
	private String name;
	private int age;
	private Grade grade;
         /*省略get/set*/

4.配置文件

Grade.hbm.xml【令inverse=false,之后在步骤7再测试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="cn.siggy.pojo">
	<class name="Grade">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"/>
		<!-- set是 Grade中的集合属性  name属性名称 -->
		<!-- inverse设置由谁来管理关系 如果为false则双方都可以管理关系
		如果为true则关系由另一方来管理,且必须由多的一方来管理,默认
                inverse=false-->
		<set name="students" inverse="false">
			<!-- key表示外键  column外键列名-->
			<key column="grade_id"></key>
			<!-- one-to-many 一对多  类Grade 中  students 所表示类型 -->
			<one-to-many class="Student"/>
		</set>
	</class>
</hibernate-mapping>

  

  

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="cn.siggy.pojo">
	<class name="Student">
		<id name="id">
			<generator class="native"></generator>
		</id>
		<property name="name"/>
		<property name="age"/>
		<!--
			cascade 级联:让操作级联到子实体
			save-update:保存和更新多的一端数据时,一的一端的数据可以一起保存和更新
			none:不级联
			delete:删除级联-不能在多的一端使用
			all:表示所有操作都级联
		 -->
		<many-to-one name="grade" class="Grade" column="grade_id"
		 ></many-to-one>
	</class>
</hibernate-mapping>

  

5.0 测试代码【当inverse=false时的测试结果】

package cn.siggy.test;

import java.sql.SQLException;

import javax.sql.rowset.serial.SerialException;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.Test;

import cn.siggy.pojo.Grade;
import cn.siggy.pojo.Student;
import cn.siggy.util.HibernateUtil;

public class HibernateTest {
	@Test
	public void testCreateDB(){
		Configuration cfg = new Configuration().configure();
		SchemaExport se = new SchemaExport(cfg);
		//第一个参数 是否生成ddl脚本  第二个参数  是否执行到数据库中
		se.create(true, true);
	}
	@Test
	public void testSave() throws HibernateException, SerialException, SQLException{
		Session session = null;
		Transaction tx = null;
		try{
			session = HibernateUtil.getSession();
			tx = session.beginTransaction();
			Grade grade = new Grade();
			grade.setName("基础");

//			/*方式一:双方都维护关系*/
//			Student stu = new Student();
//			stu.setName("张三疯");
//			stu.setAge(22);
//			stu.setGrade(grade);
//			Student stu1 = new Student();
//			stu1.setName("老王");
//			stu1.setAge(23);
//			stu1.setGrade(grade);
//
//			grade.getStudents().add(stu);
//			grade.getStudents().add(stu1);
//			session.save(grade);
//			session.save(stu);
//			session.save(stu1);

			/*方式二:一的一端维护关系*/
			Student stu = new Student();
			stu.setName("张三疯");
			stu.setAge(22);
			Student stu1 = new Student();
			stu1.setName("老王");
			stu1.setAge(23);

			grade.getStudents().add(stu);
			grade.getStudents().add(stu1);
			session.save(grade);
			session.save(stu);
			session.save(stu1);

//			/*方式三:由多的一方维护关系*/
//			Student stu = new Student();
//			stu.setName("张三疯");
//			stu.setAge(22);
//			stu.setGrade(grade);
//			Student stu1 = new Student();
//			stu1.setName("老王");
//			stu1.setAge(23);
//			stu1.setGrade(grade);
//
//			session.save(grade);
//			session.save(stu);
//			session.save(stu1);

			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);
//			session.delete(grade);

			Student stu = (Student) session.get(Student.class, 1);
			session.delete(stu);

			tx.commit();
		}catch (HibernateException e) {
			if(tx!=null)
				tx.rollback();
			e.printStackTrace();
			//throw e;
		}finally{
			HibernateUtil.closeSession();
		}
	}
}

  

6.测试结果:

1.方式一:双方式都维护关系

控制台信息:

数据库表信息:



2.方式二:由一的一端维护关系【结果和方式一一样】



3.方式三:由多的一端维护关系

控制台信息:

数据库表信息:




7.当inverse=true时,测试结果如下:【关系由另一方维护,且必须由多的一方维护】

1.方式一:

2.方式二:【多的一方没有维护,故student表的grade_id=null】

3.方式三:

时间: 2024-12-08 05:31:51

【7.3.1】级联操作--inverse的相关文章

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

总结: Cascade:对级联操作进行限制,有如下几个参数: all : 所有情况下均进行关联操作.  none:所有情况下均不进行关联操作.这是默认值.  save-update:在执行save/update/saveOrUpdate时进行关联操作.  delete:在执行delete时进行关联操作. Inverse:在一对多模型中,只能在一的一方设置,inverse的作用就是在级联发生后,会再次更新子表数据的外键为主表的主键.确保子表外键不会为空. 下面演示一个班级学生的例子(一对多): 班

hibernate中关系操作(inverse)和级联操作(cascade)详解

以用户.角色.用户文件为例讲解inverse(关系操作)和(cascade)操作 inverse 取值 true(不维护关系)或false(维护关系  默认为false) 该属性主要操作的是外键 cascade 取值null(默认值).save-update .all .delete 用户.角色是多对多的关系 用户的映射文件表示: <hibernate-mapping> <class name="com.xing.elec.domain.ElecUser" table

Hibernate 配置文件属性之 级联操作cascade 性能优化inverse

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping pack

hibernate的中的查询与级联操作

1.Criteria查询接口适用于组合多个限制条件来搜索一个查询集. 要使用Criteria,需要遵循以下步骤: *创建查询接口: Criteria criteria=session.createCriteria(User.class); *设置查询条件: criteria.add(Restrictions.gt("age",10); *查询数据:      List<User> list=criteria.list(); 2.关系映射:一个用户(cust_customer

hibernate级联操作

在关系中加入如下代码分别表示不同的级联操作 例如: <many-to-one name="inv" column="igid" class="entity.inventory" cascade="delete"></many-to-one> 1.级联保存 cascade=”save-update” 2.级联删除 cascade=”delete” 3.所有级联 cascade=”all 4.不使用级联 c

Hibernate(八)__级联操作、struts+hibernate+接口编程架构

级联操作 所谓级联操作就是说,当你进行主对象某个操作时,从对象hibernate自动完成相应操作. 比如: Department <---->Student 对象关系,我希望当我删除一个department ,那么就自动删除该部门的所有学生. 再比如: bbs项目主帖<---->回帖 , 把主帖删除,那我们就希望把该主帖的回帖自动删除,这样我们可以使用级联(cascade)操作. 案例:如何配置级联操作,当删除某个部门的时候,我们自动删除其学生. 首先我们在配置文件中修改: <

实体外键约束、级联操作

[实体关系]1.一对多:在多的表,增加一个字段,用于只想该实体所悟的另外的实体的标识.2.多对多:利用一个中间表,表示实体之间的对应关系.(中间表和实体表是一对多关系) [外键约束]foreign key (class_id) references tb_class (class_id); drop table if exists tb_class; create table tb_class( class_id int primary key auto_increment, class_nam

【Hibernate学习】——级联操作

级联策略:负责控制关联两端对象到对象的级联关系的操作,包括更新.删除等,也就是说对一个对象进行更新.删除时,其它对象也受影响,比如我删除一个对象,那么跟它是多对一关系的对象也全部被删除. 在前面用了抓取策略之后,后面试了一下级联操作的注解:cascadeType.MERGE方式 @OneToOne(cascade={CascadeType.MERGE}) @JoinColumn(name="company_id") publicCompany getCompany() { return

【SSH三大框架】Hibernate基础第九篇:cascade关联关系的级联操作

这里要说的是Hibernate的关联关系的级联操作,使用cascade属性控制. 依旧用部门和员工举例.多个员工相应一个部门(多对一关联关系) 员工类:Employee.java package cn.itcast.hibernate.domain; public class Employee { private int id; private String name; private Department depart; public int getId() { return id; } pu