技术分析之Hibernate的关联关系映射之一对多映射

本文介绍了一对多关系在Hibernate中的配置方法及操作实践,包括User与Order类的设计、XML映射文件详解及通过Hibernate API实现数据的增删改查。

实际开发中往往需要利用和建立一对多的表,比如客户和订单的关系,一个客户可以建立多个订单,一个订单只能被一个客户生成,所以就生成了一对多的关系,下面就来演示下配置和代码。

客户User类

package model;

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

public class User {
	private Long uid;
	private String uname;
	private String upwd;
	//对应的多表类应该用set集合,而且要初始化,否则会空指针异常
	private Set<Order> orders = new HashSet<>();
	
	public Long getUid() {

		return uid;
	}

	public void setUid(Long uid) {

		this.uid = uid;
	}

	public String getUname() {

		return uname;
	}

	public void setUname(String uname) {

		this.uname = uname;
	}

	public String getUpwd() {

		return upwd;
	}

	public void setUpwd(String upwd) {

		this.upwd = upwd;
	}

	public Set<Order> getOrders() {

		return orders;
	}

	public void setOrders(Set<Order> orders) {

		this.orders = orders;
	}

	

	@Override
	public String toString() {
		return "User [uid=" + uid + ", uname=" + uname + ", upwd=" + upwd + "]";
	}

	public User(Long uid, String uname, String upwd, Set<Order> orders) {
		super();
		this.uid = uid;
		this.uname = uname;
		this.upwd = upwd;
		this.orders = orders;
	}

	public User() {

		super();
		

	}

}

订单Order类

package model;

public class Order {
	private Long oid;
	private String oname;
	private Double oprice;
	private User user;

	public Long getOid() {

		return oid;
	}

	public void setOid(Long oid) {

		this.oid = oid;
	}

	public String getOname() {

		return oname;
	}

	public void setOname(String oname) {

		this.oname = oname;
	}

	public Double getOprice() {

		return oprice;
	}

	public void setOprice(Double oprice) {

		this.oprice = oprice;
	}

	public User getUser() {

		return user;
	}

	public void setUser(User user) {

		this.user = user;
	}


	@Override
	public String toString() {
		return "Order [oid=" + oid + ", oname=" + oname + ", oprice=" + oprice + "]";
	}

	public Order(Long oid, String oname, Double oprice, User user) {
		super();
		this.oid = oid;
		this.oname = oname;
		this.oprice = oprice;
		this.user = user;
	}

	public Order() {

		super();
		

	}

}

User.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>
	<class name="model.User" table="user">
		<id name="uid">
			<generator class="native"></generator>
		</id>
		<property name="uname"></property>
		<property name="upwd"></property>
		<!-- set 配置在一方:表示一个集合
    		set name:name是一方中的set<多方>的属性名
    		key:表中的 外键名  column外键名
    		
    		
    		one-to-many class:配置的是多方的权限定名
    		cascade="save-update" :级联保存
    		
    		cascade="save-update,delete":级联删除  和级联更新     就相当于写个all:all就包括级联更新级联删除
    		
    		cascade="delete-orphan":孤儿删除
    		
    		一对多关系:一方默认是维护关键关系  inverse="false":维护外键
    		inverse:反转的意思 是否把维护外键的活交给对方处理
    		
    		一对多可以不用放弃外键维护  但是多对多必须要有一方来放弃对外键的维护。
    		 -->
		<set name="orders" cascade="all-delete-orphan">
			<key column="uid"></key>
			<one-to-many class="model.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>
<class name="model.Order" table="order1">
<id name="oid">
<generator class="native"></generator>
</id>
<property name="oprice"></property>
<property name="oname"></property>
<!-- 多方还要配置一方的对象属性
    	many-to-one:用来配置在多方的  一方的属性
    	name:多方中的一方的属性名
    	column:外键名
    	 -->
<many-to-one name="user" column="uid" class="model.User" cascade="save-update"></many-to-one>
</class>
</hibernate-mapping>

hibernate.cfg.xml配置只需要安装基本配置然后加上对应的

<mapping resource="model/User.hbm.xml"/>
<mapping resource="model/Order.hbm.xml"/>
就可以了。

然后demo来操作一对多表的操作

HibernateUtile的代码

package utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
	private static final Configuration cfg;
	private static final SessionFactory factory;

	static {

		cfg = new Configuration().configure();
		factory = cfg.buildSessionFactory();
		// 当jvm虚拟机被关闭的时候会走该方法
		Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
			public void run() {
				factory.close();
				System.out.println("factory被关闭");
			}
		}));
	}

	public static Session openSession() {
		return factory.openSession();
	}
}

test类

package test;

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

import model.Order;
import model.User;
import utils.HibernateUtil;
//操作一对多的关系
public class demo1 {
	@Test
	public void run1() {
		Session session = HibernateUtil.openSession();
		Transaction ts = session.beginTransaction();
		User user = new User();
		user.setUname("小李");
		user.setUpwd("2333");
		Order order = new Order();
		Order order2 = new Order();
		order.setOname("货物1");
		order.setOprice(12.6);
		order2.setOname("货物2");
		order2.setOprice(10.8);

		user.getOrders().add(order);
		user.getOrders().add(order2);

		session.save(user);
//		因为设置了级联更新,所以只需要保存user就可以,
//		session.save(order2);
//		session.save(order);
		ts.commit();
		session.close();

	}
	//效果和run1相同
	@Test
	public void run2() {
		Session session = HibernateUtil.openSession();
		Transaction ts = session.beginTransaction();
		User user = new User();
		user.setUname("小李");
		user.setUpwd("2333");
		Order order = new Order();
		Order order2 = new Order();
		order.setOname("货物1");
		order.setOprice(12.6);
		order2.setOname("货物2");
		order2.setOprice(10.8);

		order.setUser(user);
		order2.setUser(user);
//		因为设置了级联更新,所以只需要保存order就可以,
//		session.save(user);
		session.save(order2);
		session.save(order);

		ts.commit();
		session.close();

	}
	/*
	 * hibernate在是默认可以删除一方的,但是多方会把外键置为null
	 * 级联删除,删除一方的时候,去级联删除多方
	 * 
	 * */
	//级联删除
	@Test
	public void run3() {
		Session session = HibernateUtil.openSession();
		Transaction ts = session.beginTransaction();
		User user = session.get(User.class, 1L);
	
		session.delete(user);
		ts.commit();
		session.close();

	}
	
	@Test
	public void run4() {
		Session session = HibernateUtil.openSession();
		Transaction ts = session.beginTransaction();
		Order order = session.get(Order.class, 1L);
		//只Schumacher了1订单,因为在Order.hbm.xml之配置了级联更新,没有配置级联删除
		session.delete(order);
		ts.commit();
		session.close();

	}
	/*
	 * inverse="true"放弃对外键的维护,保存user的时候,order里面不会有外键
	 * delete-orphan孤儿删除,只要和父亲脱离关系,父亲杀死儿子(玩笑- -)
	 * */
	//效果同run4
	@Test
	public void run5() {
		Session session = HibernateUtil.openSession();
		Transaction ts = session.beginTransaction();
		User user = session.get(User.class, 1L);
		Order order = session.get(Order.class, 1L);
		user.getOrders().remove(order);
		ts.commit();
		session.close();
	}
	
}







评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值