Hibernate进阶之单向多对一关系映射

Hibernate中实现对象与对象之间的关系:有一对一,一对多,多对多。下面来认识Hibernate的单向多对一关系。

 在配置映射文件中让我们来认识<many-to-one name="" column="" cascade=""/>多对一这个标签。

首先,我们定义两个实体类:Customer,Order。

代码如下:

Customer类:

package example.many2one_single;
/**
 * 客户(一方)
 * @author Administrator
 *
 */
public class Customer {

	private Integer id;//对应表的主键
	private String name;
	private Integer age;
	public Customer() {
	}
	public Customer(String name, Integer age) {
		super();
		this.name = name;
		this.age = age;
	}
	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 Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	
}
Order类:

package example.many2one_single;
/**
 * 订单(多的一方)
 * @author Administrator
 *
 */
public class Order {

	private Integer id;
	private String OrderNo;//订单编号
	private Integer price;//价格
	private Customer customer;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getOrderNo() {
		return OrderNo;
	}
	public void setOrderNo(String orderNo) {
		OrderNo = orderNo;
	}
	public Integer getPrice() {
		return price;
	}
	public void setPrice(Integer price) {
		this.price = price;
	}
	public Order(String orderNo, Integer price) {
		super();
		OrderNo = orderNo;
		this.price = price;
	}
	public Order() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Customer getCustomer() {
		return customer;
	}
	public void setCustomer(Customer customer) {
		this.customer = customer;
	}
	
	
}

第二步:配置映射文件,把Customer和Order的映射都写在同一个映射文件中:

CustomerOrder.hbm.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="example.many2one_single">
	<class name="Customer" table="customers">
		<id name="id" column="id" type="int">
			<generator class="native"></generator>
		</id>
		<property name="name" column="name" type="string"></property>
		<property name="age" column="age" type="int"></property>
	</class>
	<class name="Order" table="Orders">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<property name="orderNo" column="orderNo"></property>
		<property name="price" column="price"></property>
		<!--many-to-one映射多方的关联属性
		name表示关联的属性名
		column表示多方的外键列
		  -->
		<many-to-one name="customer" column="customers_id" ></many-to-one>
	</class>
</hibernate-mapping>

第三步:在mysql建表:

create table customers(
id int(5) primary key auto_increment,name varchar(50),age int(5)
);
create table orders(
	id int primary key auto_increment,
	orderNo varchar(255),
	price int(5),
	customer_id int(5),
	constraint customer_order_FK foreign key(id) references customers(id)
);

第四步,写执行代码:

package example.dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;

import example.many2one_single.Customer;
import example.many2one_single.Order;
import example.utils.HibernateUtils;

public class CustomerOrderDao {

	private static  SessionFactory sessionFactory;
	static{
		//创建configure配置文件hibernate.properties
		Configuration cfg=new Configuration();
		//加载映射文件hibernate.cfg.xml
		cfg.configure();
		//创建sessionFactory工厂对象
		sessionFactory=cfg.buildSessionFactory();
	}
	/**
	 * 先保存1客户,再保存2订单------3条SQL
	 */
	@Test
	public void test01(){
		Customer customer=new Customer("小李",14);
		Order o1=new Order("order2011",100);
		Order o2=new Order("order2012",100);
		//创建创建单项关联
		o1.setCustomer(customer);
		o2.setCustomer(customer);
		
		Session session=null;
		Transaction ts=null;
		try{
			//创建session对象
			//session= sessionFactory.openSession();
			session=HibernateUtils.getSession();
			//开启事务
			ts= session.getTransaction();
			//开始事务
			ts.begin();
			//保存对象到数据库
			session.save(o1);
			session.save(o2);
			session.save(customer);
			ts.commit();
		}catch (Exception e) {
			// TODO: handle exception
			ts.rollback();
			e.printStackTrace();
		}finally{
			//session.close();
			HibernateUtils.closeSession();
		}
	}
	/**
	 * 先保存2订单,再保存1客户------5条SQL
	 */
	@Test
	public void test02(){
		Customer customer=new Customer("小李",14);
		Order o1=new Order("order2011",100);
		Order o2=new Order("order2012",100);
		//创建创建单项关联
		o1.setCustomer(customer);
		o2.setCustomer(customer);
		
		Session session=null;
		Transaction ts=null;
		try{
			//创建session对象
			//session= sessionFactory.openSession();
			session=HibernateUtils.getSession();
			//开启事务
			ts= session.getTransaction();
			//开始事务
			ts.begin();
			//保存对象到数据库
			session.save(customer);
			session.save(o1);
			session.save(o2);
			ts.commit();
		}catch (Exception e) {
			// TODO: handle exception
			ts.rollback();
			e.printStackTrace();
		}finally{
			//session.close();
			HibernateUtils.closeSession();
		}
	}

接下来我们认识cascade="save-update/all":当我们在代码中这样写的话会出现临时对象出错异常(org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: example.many2one_single.Customer)。

/**
	 * 只保存2订单,级联保存1客户(cascade="save-update/all")
	 */
	@Test
	public void test03(){
		Customer customer=new Customer("小名",14);
		Order o1=new Order("order2011",100);
		Order o2=new Order("order2012",100);
		//创建创建单项关联
		o1.setCustomer(customer);
		o2.setCustomer(customer);
		
		Session session=null;
		Transaction ts=null;
		try{
			//创建session对象
			//session= sessionFactory.openSession();
			session=HibernateUtils.getSession();
			//开启事务
			ts= session.getTransaction();
			//开始事务
			ts.begin();
			//保存对象到数据库
			session.save(o1);
			session.save(o2);
			ts.commit();
		}catch (Exception e) {
			// TODO: handle exception
			ts.rollback();
			e.printStackTrace();
		}finally{
			//session.close();
			HibernateUtils.closeSession();
		}
	}

这是因为持久对象引用临时对象导致的错误,所以要避免这种错误,就应该在映射文件中添加 cascade="save-update"
配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="example.many2one_single">
	<class name="Customer" table="customers">
		<id name="id" column="id" type="int">
			<generator class="native"></generator>
		</id>
		<property name="name" column="name" type="string"></property>
		<property name="age" column="age" type="int"></property>
	</class>
	<class name="Order" table="Orders">
		<id name="id" column="id">
			<generator class="native"></generator>
		</id>
		<property name="orderNo" column="orderNo"></property>
		<property name="price" column="price"></property>
		<!--many-to-one映射多方的关联属性
		name表示关联的属性名
		column表示多方的外键列
		  -->
		<many-to-one name="customer" column="customers_id" cascade="save-update"></many-to-one>
	</class>
</hibernate-mapping>

只更新2订单,级联更新1客户【cascade="save-update/all"】:

/**
	 * 只更新2订单,级联更新1客户【cascade="save-update/all"】
	 */
	@Test
	public void test04(){
		Session session=null;
		Transaction ts=null;
		try{
			//创建session对象
			//session= sessionFactory.openSession();
			session=HibernateUtils.getSession();
			//开启事务
			ts= session.getTransaction();
			//开始事务
			ts.begin();
			Order o6= (Order) session.get(Order.class, 6);
			o6.setPrice(o6.getPrice()+20);
			Order o7=(Order) session.get(Order.class, 7);
			o7.setPrice(o7.getPrice()+30);
			Customer cus=o6.getCustomer();
			cus.setAge(cus.getAge()+4);
			//保存对象到数据库
			session.save(o6);
			session.save(o7);
			ts.commit();
		}catch (Exception e) {
			// TODO: handle exception
			ts.rollback();
			e.printStackTrace();
		}finally{
			//session.close();
			HibernateUtils.closeSession();
		}
	}

只删除订单,级联删除客户【cascade="delete/all"】,只删除订单,不级联删除客户【cascade="none",默认值】:

/**
	 * 只删除订单,级联删除客户【cascade="delete/all"】
	 */
	@Test
	public void test05(){
		Session session=null;
		Transaction ts=null;
		try{
			//创建session对象
			//session= sessionFactory.openSession();
			session=HibernateUtils.getSession();
			//开启事务
			ts= session.getTransaction();
			//开始事务
			ts.begin();
			Order o6= (Order) session.get(Order.class, 8);
			session.delete(o6);
			ts.commit();
		}catch (Exception e) {
			// TODO: handle exception
			ts.rollback();
			e.printStackTrace();
		}finally{
			//session.close();
			HibernateUtils.closeSession();
		}
	}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值