Hibernate(5.3.7)关联关系中的反转和级联

版权声明:版权所有@万星明 https://blog.csdn.net/qq_19533277/article/details/84893795

1、反转:

反转操作在映射文件中通过对集合的inverse属性设置,来控制关联关系和对象的级联关系。
inverse默认为false,关系的两端都能够控制,但会造成更新时出现重复更新的情况,产生多余的SQL语句。所以在实际开发中,一对多的时候,将一的一方inverse设置为true,即由多的一方维护关联关系;多对多则任意设置一方即可。(ps:inverse只对<set>、<one-to-many>、<many-to-many>有效)。

2、级联:

当主控方执行保存、更新、或删除操作时,关联对象也执行相同操作。通过对cascade属性的设置来控制是否使用级联。
cascade属性值:
- save-update:在执行save、update、或saveOrUpdate时进行关联。
- delete:在执行delete操作时进行关联
- delete-orphan:表示孤儿删除,删除所有和当前对象解除关联的对象
- all:所有情况下都进行关联,但不包括delete-orphan
- all-delete-orphan:所有情况下都进行关联
- none:所有情况下都不进行关联。这个是默认的

一对多级联保存:
保存一的同时,保存一旗下的多。

/**
	 * 一对多级联保存
	 */
	@Test
	public void testCascade1() {
		//获得session对象
		Session session = getSession();
		//通过session开启事务
		Transaction trans = session.beginTransaction();
		
		//创建一个客户对象
		Customer customer = new Customer();
		customer.setName("马化腾");
		//创建两个订单
		Order order1 = new Order(1000,"硅谷");
		Order order2 = new Order(2000, "大学城");
		//客户关联订单
		customer.getOrderSet().add(order1);
		customer.getOrderSet().add(order2);
		//仅保存客户
		session.save(customer);
		
		//提交事务
		trans.commit();
		session.close();
	}
 
         (在仅保存的那一方的xml文件中加上,cascade)
       <set name="orderSet" table="orders" cascade="save-update">
        	<!-- 外键 -->
            <key>
                <column name="customer_id"/>
            </key>
            <one-to-many class="wan.bean.Order" />
        </set>

一对多级联删除:
删除一的同时,删除一旗下的多。如果不配置xml,则只删除一,然后将一旗下的多的外键置null。

/**
	 * 一对多级联删除(如果不在xml中配置cascade="delete",则只能删除customer,然后将order的外键置null)
	 */
	@Test
	public void testCascade2() {
		//获得session对象
		Session session = getSession();
		//通过session开启事务
		Transaction trans = session.beginTransaction();
		
		//得到一个客户对象
		Customer customer = session.get(Customer.class,40023);
		//删除客户
		session.delete(customer);
		
		//提交事务
		trans.commit();
		session.close();
	}
 
 <set name="orderSet" table="orders" cascade="delete">
        	<!-- 外键 -->
            <key>
                <column name="customer_id"/>
            </key>
            <one-to-many class="wan.bean.Order" />
        </set>

一对多孤儿删除:
删除多,且只删除外键为null的多。

/**
	 * 孤儿删除:删除多,且只删除外键为null的多
	 */
	@Test
	public void testCascade3() {
		//获得session对象
		Session session = getSession();
		//通过session开启事务
		Transaction trans = session.beginTransaction();
		
		//得到一个客户对象
		Customer customer = session.get(Customer.class,40022);
		//得到客户旗下的订单
		Order order1 = session.get(Order.class,29);
		Order order2 = session.get(Order.class,30);
		//解除关系
		customer.getOrderSet().remove(order1);
		customer.getOrderSet().remove(order2);
		//提交事务
		trans.commit();
		session.close();
	}
 
 <set name="orderSet" table="orders" cascade="delete-orphan">
        	<!-- 外键 -->
            <key>
                <column name="customer_id"/>
            </key>
            <one-to-many class="wan.bean.Order" />
        </set>

多对多级联保存:

/**
	 * 级联添加(只在teacher.hbm.xml中添加级联属性为save-update)
	 */
	@Test
	public void testAdd3() {
		//获得session对象
		Session session = getSession();
		//通过session开启事务
		Transaction trans = session.beginTransaction();
		
		//创建两个老师,两个班级
		Teacher t1 = new Teacher("马云");
		Teacher t2 = new Teacher("马化腾");
		Classes c1 = new Classes("通信141");
		Classes c2 = new Classes("通信142");
				
		//建立联系
		t1.getClassesSet().add(c1);
		t1.getClassesSet().add(c2);
		t2.getClassesSet().add(c1);
		t2.getClassesSet().add(c2);
  
		session.save(t1);
		session.save(t2);
		trans.commit();
		session.close();
	}
 
  <set name="classesSet" table="classes_teacher" cascade="save-update">
            <key>
                <column name="t_id" />
            </key>
            <!-- 多对多对应Classes POJO类,该类对应中间表的c_id -->
            <many-to-many class="Classes" column="c_id"/>
        </set>

或者:

/**
	 * 级联添加(只在两张hbm.xml中都添加级联属性为save-update)
	 */
	@Test
	public void testAdd4() {
		//获得session对象
		Session session = getSession();
		//通过session开启事务
		Transaction trans = session.beginTransaction();
		
		//创建两个老师,两个班级
		Teacher t1 = new Teacher("刘强东");
		Teacher t2 = new Teacher("雷军");
		Classes c1 = new Classes("通信141");
		Classes c2 = new Classes("通信142");
				
		//建立联系
		t1.getClassesSet().add(c1);
		t1.getClassesSet().add(c2);
		t2.getClassesSet().add(c1);
		t2.getClassesSet().add(c2);
		c1.getTeacherSet().add(t1);
		c1.getTeacherSet().add(t2);
		c2.getTeacherSet().add(t1);
		c2.getTeacherSet().add(t2);
  
		session.save(t1);
		trans.commit();
		session.close();
	}

多对多级联删除:

/**
	 * 删除(无级联配置,删除该Teacher对象和中间表)
	 */
	@Test
	public void testDel2() {
		//获得session对象
		Session session = getSession();
		//通过session开启事务
		Transaction trans = session.beginTransaction();
		
		Teacher teacher = session.get(Teacher.class, 31);
		session.delete(teacher);
		trans.commit();
		session.close();
	}
 
 
 /**
     * 级联删除(在两个hbm.xml中加入级联删除,且在Classes.hbm.xml中加入inverse="true")
     * 将会删除和该Teacher有关的一切
	  */
	@Test
	public void testDel1() {
		//获得session对象
		Session session = getSession();
		//通过session开启事务
		Transaction trans = session.beginTransaction();
		
		Teacher teacher = (Teacher) session.get(Teacher.class, 30);
		session.delete(teacher);
		trans.commit();
		session.close();
	}

猜你喜欢

转载自blog.csdn.net/qq_19533277/article/details/84893795