hibernate_day03_一对多相关操作

hibernate_day03_MySQL数据库-表与表之间的多对多关系-实例

hibernate_day03_一对多相关操作

【1】一对多关系只保存一边是否可以 :不可以,会报错(瞬时对象异常)。

【2】一对多的级联操作 :

  1. 什么叫做级联
    1. 级联指的是,操作一个对象的时候,是否会同时操作其关联的对象。
  2. 级联是有方向性
    1. 操作一的一方的时候,是否操作到多的一方
    2. 操作多的一方的时候,是否操作到一的一方

【3】级联保存或更新 :

【4】测试对象的导航 :

【5】级联删除 :

【6】一对多设置了双向关联产生多余的SQL语句 :

【7】区分cascade和inverse :

(1)HibernateDemo1.java :

package com.itheima.hibernate.demo1;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import com.itheima.hibernate.domain.Customer;
import com.itheima.hibernate.domain.LinkMan;
import com.itheima.hibernate.utils.HibernateUtils;

/**
 * 
 * * 一对多的测试类
 * */
public class HibernateDemo1 {

//	@Test
//	// 保存2个客户 和 3个联系人 并且建立好关系
//	public void demo1() {
//		Session session = HibernateUtils.getCurrentSession();
//		Transaction tx = session.beginTransaction();
//
//		// 创建两个客户
//		Customer customer1 = new Customer();
//		customer1.setCust_name("wd");
//		Customer customer2 = new Customer();
//		customer2.setCust_name("zh");
//
//		// 创建三个联系人
//		LinkMan linkMan1 = new LinkMan();
//		linkMan1.setLkm_name("fengjie");
//		LinkMan linkMan2 = new LinkMan();
//		linkMan2.setLkm_name("ruhua");
//		LinkMan linkMan3 = new LinkMan();
//		linkMan3.setLkm_name("wangcai");
//
//		// 设置关系: 【一个客户 对应 多个联系人。】
//		linkMan1.setCustomer(customer1);
//		linkMan2.setCustomer(customer1);
//		linkMan3.setCustomer(customer2);
//		customer1.getLinkMans().add(linkMan1);
//		customer1.getLinkMans().add(linkMan2);
//		customer2.getLinkMans().add(linkMan3);
//
//		// 保存数据:
//		session.save(linkMan1);
//		session.save(linkMan2);
//		session.save(linkMan3);
//		session.save(customer1);
//		session.save(customer2);
//
//		tx.commit();
//	}
//
//	@Test
//	// 一对多关系只保存一边[客户 or 联系人]是否可以:不可以[报错]
//	public void demo2() {
//		Session session = HibernateUtils.getCurrentSession();
//		Transaction tx = session.beginTransaction();
//
//		Customer customer = new Customer(); //瞬时
//		customer.setCust_name("zhaohong");
//
//		LinkMan linkMan = new LinkMan();
//		linkMan.setLkm_name("ruhua");
//		
//		customer.getLinkMans().add(linkMan);// 客户关联联系人
//		linkMan.setCustomer(customer); // 联系人关联客户
//
//		// 只保存一边是否可以:
//		// 不可以,报一个瞬时对象异常:持久态对象关联了一个瞬时态对象。
//		//session.save(customer);
//		session.save(linkMan);
//		
//		//通过级联操作,可解决 异常
//
//		tx.commit();
//	}
//
//	@Test
//	/**
//	 * 级联保存或更新操作: * 保存客户级联联系人,操作的主体是客户对象,需要在Customer.hbm.xml中进行配置 *
//	 * <set name="linkMans" cascade="save-update">
//	 * 【session.save(customer);   保存谁,配置谁   】
//	 */
//	public void demo3() {
//		Session session = HibernateUtils.getCurrentSession();
//		Transaction tx = session.beginTransaction();
//
//		Customer customer = new Customer();
//		customer.setCust_name("zhaohong");
//
//		LinkMan linkMan = new LinkMan();
//		linkMan.setLkm_name("ruhua");
//
//		customer.getLinkMans().add(linkMan);
//		linkMan.setCustomer(customer);
//
//		session.save(customer);
//
//		tx.commit();
//	}
//
//	@Test
//	/**
//	 * 级联保存或更新操作: * 保存联系人级联客户,操作的主体是联系人对象,需要在LinkMan.hbm.xml中进行配置 *
//	 * <many-to-one name="customer" cascade="save-update" class=
//	 * "com.itheima.hibernate.domain.Customer" column="lkm_cust_id"/>
//	 */
//	public void demo4() {
//		Session session = HibernateUtils.getCurrentSession();
//		Transaction tx = session.beginTransaction();
//
//		Customer customer = new Customer();
//		customer.setCust_name("libing");
//
//		LinkMan linkMan = new LinkMan();
//		linkMan.setLkm_name("fengjie");
//
//		customer.getLinkMans().add(linkMan);
//		linkMan.setCustomer(customer);
//
//		session.save(linkMan);
//
//		tx.commit();
//	}

//	@Test
//	/**
//	 * 测试对象的导航 
//	 * * 前提:一对多的双方都设置cascade="save-update"
//	 */
//	public void demo5() {
//		Session session = HibernateUtils.getCurrentSession();
//		Transaction tx = session.beginTransaction();
//
//		Customer customer = new Customer();
//		customer.setCust_name("libing");
//
//		LinkMan linkMan1 = new LinkMan();
//		linkMan1.setLkm_name("fengjie");
//		LinkMan linkMan2 = new LinkMan();
//		linkMan2.setLkm_name("ruhua");
//		LinkMan linkMan3 = new LinkMan();
//		linkMan3.setLkm_name("furong");
//		
//		// 凤姐找李冰,李冰找如花、芙蓉
//		linkMan1.setCustomer(customer); // 1号联系人关联客户
//		customer.getLinkMans().add(linkMan2); // 客户关联2号联系人
//		customer.getLinkMans().add(linkMan3); // 客户关联3号联系人
//
//		// 双方都设置了cascade
//		session.save(linkMan1); // 发送几条insert语句 4条
//		// [session.save(linkMan1);]  linkMan1、[linkMan1.setCustomer(customer);] customer、
//		// [customer.getLinkMans().add(linkMan2);]linkMan2、[customer.getLinkMans().add(linkMan3);]linkMan3  所以,4条语句
//		
//		//session.save(customer); // 发送几条insert语句  3条
//		// customer.getLinkMans().add(linkMan2); \ customer.getLinkMans().add(linkMan3);
//
//		//session.save(linkMan2); // 发送几条insert语句  1条
//
//		tx.commit();
//	}
//
//	@Test
//	/**
//	 * 级联删除:
//	 * * 删除客户级联删除联系人,删除的主体是客户,需要在Customer.hbm.xml中配置
//	 * * <set name="linkMans" cascade="delete">
//	 * * cascade="save-update,delete" :同时具有2个功能。
//	 */
//	public void demo6(){
//		Session session = HibernateUtils.getCurrentSession();
//		Transaction tx = session.beginTransaction();
//		
//		// 没有设置级联删除,默认情况:修改了联系人的外键,删除客户
//		/*Customer customer = session.get(Customer.class, 1l);
//		session.delete(customer);*/
//		
//		// 删除客户,同时删除联系人
//		Customer customer = session.get(Customer.class, 1l);
//		session.delete(customer);
//		
//		tx.commit();
//	}
//	
//	@Test
//	/**
//	 * 级联删除:
//	 * * 删除联系人级联删除客户,删除的主体是联系人,需要在LinkMan.hbm.xml中配置
//	 * * <many-to-one name="customer" cascade="delete">
//	 */
//	public void demo7(){
//		Session session = HibernateUtils.getCurrentSession();
//		Transaction tx = session.beginTransaction();
//		
//		// 删除客户,同时删除联系人
//		/**
//		 * 先查询,再删除。
//		 * 不能直接创建对象去删除。创建对象,集合为空,无法删除。
//		 * get()后,查询客户关联的集合,有数据,可删除。
//		 */
//		LinkMan linkMan = session.get(LinkMan.class, 3l);
//		session.delete(linkMan);
//		
//		tx.commit();
//	}
	
//	@Test
//	/**
//	 * 将2号联系人原来归1号客户,现在改为2号客户
//	 */
//	public void demo8(){
//		Session session = HibernateUtils.getCurrentSession();
//		Transaction tx = session.beginTransaction();
//		
//		// 查询2号联系人
//		LinkMan linkMan = session.get(LinkMan.class, 2l);//持久态对象
//		// 查询2号客户
//		Customer customer = session.get(Customer.class, 2l);//持久态对象
//		// 双向的关联
//		linkMan.setCustomer(customer);
//		customer.getLinkMans().add(linkMan);
//		
//		//持久态对象发生变化,自动更新数据库
//		
//		tx.commit();
//	}
	
	@Test
	/**
	 * 区分cascade和inverse的区别
	 */
	public void demo9(){
		Session session = HibernateUtils.getCurrentSession();
		Transaction tx = session.beginTransaction();
		
		Customer customer = new Customer();
		customer.setCust_name("libing");
		
		LinkMan linkMan = new LinkMan();
		linkMan.setLkm_name("fengjie");
		
		customer.getLinkMans().add(linkMan);
		
		// 条件在Customer.hbm.xml上的set中配置了cascade="save-update" inverse="true"
		/**
		 * Customer.hbm.xml : <set name="linkMans" cascade="save-update" inverse="true">
		 * LinkMan.hbm.xml  : <many-to-one name="customer" class="com.itheima.hibernate.domain.Customer" column="lkm_cust_id"/>
		 */
		session.save(customer); // 客户会插入到数据库,联系人也会插入到数据库,但是外键为null
		/* cascade : 控制对象的关联对象。操作关联对象【客户进入数据库,客户关联的对象也会进入数据库】
		 * inverse="true" : 控制一的一方能不能维护外键。true放弃外键
		 */
		
		
		tx.commit();
	}
}

(2)Customer.hbm.xml :

<?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>

	<!-- name是Customer类的全路径 -->
	<class name="com.itheima.hibernate.domain.Customer" table="cst_customer">
		
		<!-- 建立OID与主键映射 -->
		<id name="cust_id" column="cust_id">
			<!-- 主键生成策略 -->
			<generator class="native"/>
		</id>
		
		<!-- 建立普通属性与数据库表字段映射 -->
		<property name="cust_name" column="cust_name" />
		<property name="cust_source" column="cust_source"/>
		<property name="cust_industry" column="cust_industry"/>
		<property name="cust_level" column="cust_level"/>
		<property name="cust_phone" column="cust_phone"/>
		<property name="cust_mobile" column="cust_mobile"/>
		
		<!--   配置一对多的映射:放置的多的一方的集合 -->
		<!-- set标签 :
				* name	:多的一方的对象集合的属性名称。[ Customer.java类 ]
				* cascade:级联【save-update 保存或更新】
				* inverse:放弃外键维护权true。   
				cascade="save-update,delete" 同时具有2个功能。
				-->
		<set name="linkMans" cascade="save-update" inverse="true">
			<!--  key标签 : 【column :多的一方的外键的名称。】-->
			<key column="lkm_cust_id"/>
			
			<!--  one-to-many标签 : 【class : 多的一方的类的全路径。】-->
			<one-to-many class="com.itheima.hibernate.domain.LinkMan"/>
		</set>
	</class>
</hibernate-mapping>

(3)LinkMan.hbm.xml :

<?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>

	<!-- name是Customer类的全路径 -->
	<class name="com.itheima.hibernate.domain.LinkMan" table="cst_linkman">
		
		<!-- 建立OID与主键映射 -->
		<id name="lkm_id" column="lkm_id">
			<!-- 主键生成策略 -->
			<generator class="native"/>
		</id>
		
		<!-- 建立普通属性与表字段映射 ; name与column相等,column可省略-->
		<property name="lkm_name"/>
		<property name="lkm_gender"/>
		<property name="lkm_phone"/>
		<property name="lkm_mobile"/>
		<property name="lkm_email"/>
		<property name="lkm_qq"/>
		<property name="lkm_position"/>
		<property name="lkm_memo"/>
		
		<!-- 【联系人:多】     配置多对一的关系:放置的是一的一方的对象 -->
		<!-- 多对一
			many-to-one标签
				* name		: 一的一方的对象的属性名称。【LinkMan.java类】
				* class		: 一的一方的类的全路径。
				* column	: 在多的一方的表的外键的名称。 -->
		<many-to-one name="customer" class="com.itheima.hibernate.domain.Customer" column="lkm_cust_id"/>
		
	</class>
</hibernate-mapping>

博主QQ : 386335886 

代码来源 :bilibili网站(https://www.bilibili.com/video/av33127718?p=31

夫心起于善,善虽未为,而吉神已随之。其有曾行恶事,后自改悔,诸恶莫作,众善奉行,久久必获吉庆,所谓转祸为福也。
故吉人语善、视善、行善,一日有三善,三年天必降之福。凶人语恶、视恶、行恶,一日有三恶,三年天必降之祸。胡不勉而行之?

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

upward337

谢谢老板~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值