domain:

Customer:

 

package com.hcx.domain;

import java.util.HashSet;
import java.util.Set;

public class Customer {
	private Integer id;
	private String name;
	//在1 的一方,表达持有多的一方的引用=>使用集合
	private Set<Order> orders = new HashSet<Order>();
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Set<Order> getOrders() {
		return orders;
	}
	public void setOrders(Set<Order> orders) {
		this.orders = orders;
	}
	
	
}

 

 

 

 

 

Order:

 

package com.hcx.domain;

public class Order {
	private Integer id;
	private String name;
	
	private Customer customer;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Customer getCustomer() {
		return customer;
	}

	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
	
	
}

 

 

 

 

 

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 package="com.hcx.domain" >
 	<class name="Customer" table="t_customer"  >
		<id name="id" column="id"    >
			<generator class="native"></generator>
		</id> 	
		<property name="name" column="name" type="string" ></property>
 		
 		<!-- 表达一对多关系中的集合
 			name:集合的属性名称
 			inverse: 是否将关系的维护反转给对方. 默认值: false
 				   true: 在Customer 中 放弃维护外键关系
 				   
 			cascade :级联操作
 				save-update:级联保存,级联修改. 保存A时,同时保存B. 
				delete:删除A,同时删除B,AB都不存在
				delete-orphan:孤儿删除,解除关系,同时将B删除,A存在的。
				如果需要配置多项,使用逗号分隔。<set cascade="save-update,delete">
				
				all : save-update 和 delete 整合
				all-delete-orphan : 三个整合
 				
 		 -->
 		<set name="orders" inverse="false" cascade="all-delete-orphan"  >
 			<!--
 				key 用来描述外键
 				column : 外键的值
 			  -->
 			<key column="cid" ></key>
 			<!-- one-to-many 表达, Customer 与orders 的关系是一对多
 				class: 表达关联的另一方的完整类名
 			 -->
 			<one-to-many class="Order" />
 		</set>
 	</class>
 </hibernate-mapping>

 

 

 

 

 

Order.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 package="com.hcx.domain" >
 	<class name="Order" table="t_order"  >
		<id name="id" column="id"    >
			<generator class="native"></generator>
		</id> 	
		<property name="name" column="name" type="string" ></property>
 		
 		<!-- 表达多对一关系 
 			name: 引用的属性名称
 			column: 外键的列名
 			class: 我引用的Order的完整类名
 		-->
 		<many-to-one name="customer" column="cid" class="Customer"   ></many-to-one>
 	</class>
 </hibernate-mapping>

 

 

 

 

 

hibernate.cfg.xml:

 

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

<hibernate-configuration>
<session-factory>
	<!-- property 元素用于配置Hibernate中的属性
		键:值 
	-->
	<!-- hibernate.connection.driver_class : 连接数据库的驱动  -->
	<property name="hibernate.connection.driver_class">
		com.mysql.jdbc.Driver
	</property>
	<!-- hibernate.connection.username : 连接数据库的用户名 -->
	<property name="hibernate.connection.username">root</property>
	<!-- hibernate.connection.password : 连接数据库的密码 -->
	<property name="hibernate.connection.password">1234</property>
	<!-- hibernate.connection.url : 连接数据库的地址,路径 -->
	<property name="hibernate.connection.url">
		jdbc:mysql://localhost:3306/EE19Day02
	</property>

	<!-- show_sql: 操作数据库时,会 向控制台打印sql语句 -->
	<property name="show_sql">true</property>
	<!-- format_sql: 打印sql语句前,会将sql语句先格式化  -->
	<property name="format_sql">true</property>
	<!-- hbm2ddl.auto: 生成表结构的策略配置
		update(最常用的取值): 如果当前数据库中不存在表结构,那么自动创建表结构. 
		如果存在表结构,并且表结构与实体一致,那么不做修改
		如果存在表结构,并且表结构与实体不一致,那么会修改表结构.会保留原有列.
		create(很少):无论是否存在表结构.每次启动Hibernate都会重新创建表结构.(数据会丢失)
		create-drop(极少): 无论是否存在表结构.每次启动Hibernate都会重新创建表结构.每次Hibernate运行结束时,删除表结构.
		validate(很少):不会自动创建表结构.也不会自动维护表结构.Hibernate只校验表结构. 如果表结构不一致将会抛出异常.
	-->
	<property name="hbm2ddl.auto">update</property>

	<!-- 数据库方言配置 
		org.hibernate.dialect.MySQLDialect (选择最短的)
	-->
	<property name="hibernate.dialect">
		org.hibernate.dialect.MySQLDialect
	</property>



	<!-- hibernate.connection.autocommit: 事务自动提交
		<property name="hibernate.connection.autocommit">true</property>
	-->

	<!-- 将Session与线程绑定=> 只有配置了该配置,才能使用getCurrentSession -->
	<property name="hibernate.current_session_context_class">
		thread
	</property>
	<!-- 引入ORM 映射文件 
		填写src之后的路径
	-->
	<mapping resource="com/hcx/domain/User.hbm.xml" />
	<mapping resource="com/hcx/domain/Customer.hbm.xml" />
	<mapping resource="com/hcx/domain/Order.hbm.xml" />
</session-factory>
</hibernate-configuration>

 

 

一对多关系:

 

package com.hcx.e_one2many;

import java.util.Set;

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

import com.hcx.domain.Customer;
import com.hcx.domain.Order;
import com.hcx.utils.HibernateUtils;
//测试 一对多关系
public class Demo1 {
	@Test
	//1 测试1对多关系中,保存操作
	//共打印5条语句
	//前3条打印insert	=> 保存对象,维护外键
	//后两条打印update => 维护外键
	//解决=>  单纯指定 关系由其中一方来维护.另一方不维护关系.
	//注意=> 外键维护的放弃,只能由非外键所在对象来放弃.
	//Customer  inverse属性: true
	//只打印3条语句=> 外键由order自己来维护
	
	public void fun1(){
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		//------------------------------------------------
		Customer c = new Customer();
		c.setName("tom");
		
		Order o1 = new Order();
		o1.setName("肥皂");
		
		Order o2 = new Order();
		o2.setName("蜡烛");
		
		//c.getOrders().add(o1);//维护关系
		//c.getOrders().add(o2); //维护关系
		
		o1.setCustomer(c);//维护关系
		o2.setCustomer(c);//维护关系
		
		session.save(c);//保存对象
		session.save(o1);//保存对象
		session.save(o2);//保存对象
		
		//------------------------------------------------
		session.getTransaction().commit();
		session.close(); // 游离状态
	}
	//多表关系=> 删除
	//删除 用户时 ,会先移除 Customer中引用的外键.然后再删除Customer
	
	// 结论: 维护一方的对象时,会自动维护另一方的关系
	// Customer 的 inverse属性: true
	// 会报错 => Customer不负责维护外键, 直接删除Customer 会导致,order引用了无效的id.违反了外键约束.
	@Test
	public void fun2(){
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		//------------------------------------------------
		
		Customer c = (Customer) session.get(Customer.class, 3);
		
		// Customer 的 inverse属性: true 
		
		Set<Order> set = c.getOrders();
		for(Order o : set){
			o.setCustomer(null);//设置订单不属于任何Customer
		}
		
		session.delete(c);
		
		//------------------------------------------------
		session.getTransaction().commit();
		session.close(); // 游离状态
	}
	
	//什么时候配置inverse属性?
	// 主要看业务. 如果一的一方经常需要维护外键 = 在1的一方不要配置inverse属性.
}

 

 

 

 

 

级联保存和修改:

 

package com.hcx.e_one2many;

import java.util.Set;

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

import com.hcx.domain.Customer;
import com.hcx.domain.Order;
import com.hcx.utils.HibernateUtils;
//测试 一对多关系  级联保存 级联修改
public class Demo2 {
	@Test
	//增
	//我们希望在保存Customer时,自动将未保存的Orders当中的Order保存
	//cascade: save-update
	public void fun1(){
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		//------------------------------------------------
		Customer c = new Customer();
		c.setName("tom");
		
		Order o1 = new Order();
		o1.setName("肥皂");
		
		Order o2 = new Order();
		o2.setName("蜡烛");
		
		c.getOrders().add(o1);//维护关系
		c.getOrders().add(o2); //维护关系
		
		
		/*
		o1.setCustomer(c);//维护关系
		o2.setCustomer(c);//维护关系
		 */		
		
		session.save(c);//保存对象
		//session.save(o1);//保存对象
		//session.save(o2);//保存对象
		
		//------------------------------------------------
		session.getTransaction().commit();
		session.close(); // 游离状态
	}
	@Test
	//增  
	//我们希望在保存Customer时,自动将未保存的Orders当中的Order保存
	//cascade: save-update
	public void fun2(){
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		//------------------------------------------------
		
		Customer c = (Customer) session.get(Customer.class, 8);//1条 select
		
		for(Order o :c.getOrders()){ // 1条 select
			o.setName("哇哈哈"); // 修改订单
		}
		
		//------------------------------------------------
		session.getTransaction().commit();//因为设置级联修改,自动将订单的修改保存到数据
										  //update语句
		session.close(); // 游离状态
	}
	
	@Test
	//cascade: delete
	//删除Customer时 ,会将Customer下的订单一并删除
	//inverse : false   6条sql语句   
	//inverse : true    5条sql语句 比上面少一条维护外键
			
	public void fun3(){
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		//------------------------------------------------
		
		Customer c = (Customer) session.get(Customer.class, 7);//1条 select
		
		
		session.delete(c);//删除Customer
						 // 删除两个Order
		
		//------------------------------------------------
		session.getTransaction().commit();
										  
		session.close(); // 游离状态
	}
	
	@Test
	//cascade: delete
	//操作的两方cascade值都为delete
	//需要注意: 千万不要在两方都配置 级联删除. 删除任何一方,会导致整个关系链对象全部删除.
	public void fun4(){
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		//------------------------------------------------
		Order o  = (Order) session.get(Order.class, 9);//select
		
		session.delete(o);//delete删除当前order
		
							//找到所有关联的Customer删除 select
							// delete Customer
							// Customer配置了级联删除=> select 找下面的order
							// 删除所有Order
							//删除Customer
		
		//------------------------------------------------
		session.getTransaction().commit();
										  
		session.close(); // 游离状态
	}
}

 

 

 

 

 

级联删除:孤儿删除:

 

package com.hcx.e_one2many;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

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

import com.hcx.domain.Customer;
import com.hcx.domain.Order;
import com.hcx.utils.HibernateUtils;
//测试 一对多关系
public class Demo3 {
	@Test
	//inverse:false
	//cascade: delete-orphan 孤儿删除 => 当没有任何外键引用Order时,order 会被删除
	public void fun1(){
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		//------------------------------------------------
			Customer c = (Customer) session.get(Customer.class, 9);
			Iterator<Order> it = c.getOrders().iterator();
			//注意: 删除Customer下的订单时,不能使用 c.setOrders(null); c.setOrders(new HashSet());
			while(it.hasNext()){ // 遍历Customer下的订单,并将订单删除 => 维护关系
				it.next();
				it.remove();
			}
			//------------------------------------------------
			session.getTransaction().commit();
			session.close(); // 游离状态
	}
	
	
}

 

 

 

 

 

级联删除:整合:

 

package com.hcx.e_one2many;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

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

import com.hcx.domain.Customer;
import com.hcx.domain.Order;
import com.hcx.utils.HibernateUtils;
//测试 一对多关系
public class Demo4 {
	@Test
	//cascade: all-delete-orphan => 相当于配置 save-update,delete,delete-orphan
	public void fun1(){
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		//------------------------------------------------
		Customer c = new Customer();
		c.setName("tom");
		
		Order o1 = new Order();
		o1.setName("肥皂");
		
		Order o2 = new Order();
		o2.setName("蜡烛");
		
		c.getOrders().add(o1);//维护关系
		c.getOrders().add(o2); //维护关系
		
		session.save(c);
		//------------------------------------------------
			session.getTransaction().commit();
			session.close(); // 游离状态
	}
	@Test
	//cascade: all-delete-orphan => 相当于配置 save-update,delete,delete-orphan
	public void fun2(){
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		//------------------------------------------------
		Customer c = (Customer) session.get(Customer.class, 10);
		session.delete(c);
		//------------------------------------------------
			session.getTransaction().commit();
			session.close(); // 游离状态
	}
	
	
	@Test
	//cascade: all-delete-orphan => 相当于配置 save-update,delete,delete-orphan
	public void fun3(){
		Session session = HibernateUtils.openSession();
		session.beginTransaction();
		//------------------------------------------------
		Customer c = (Customer) session.get(Customer.class, 12);

		Iterator<Order> it = c.getOrders().iterator();
		
		while(it.hasNext()){ // 遍历Customer下的订单,并将订单删除 => 维护关系
			it.next();
			it.remove();
		}
		
		//------------------------------------------------
			session.getTransaction().commit();
			session.close(); // 游离状态
	}
}