Hibernate多对一配置

hibernate中的多对一配置有两种情况:

一种是子表的外键对应主表的主键id。

另一种是子表的外键对应主表的非主键字段,一般是一个唯一的字段。(常见的场景是订单主表跟订单产品明细表,主表跟子表都是用id作为主键,但是两者之间通过orderNo(订单号)来关联)

 

下面根据这两种情况,简单介绍一下hibernate映射文件的配置。

第一种情况,假设主表是部门表(department),字表是员工表(employee)。

domain类如下:

package com.xigua.domain;


public class Department {
	
	/**
	 * 主键id
	 */
	private Long id;  
	
	/**
	 * 部门名称
	 */
	private String departName;

	public Long getId() {
		return id;
	}

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

	public String getDepartName() {
		return departName;
	}

	public void setDepartName(String departName) {
		this.departName = departName;
	}

}

 

package com.xigua.domain;

/**
 * 员工
 * @author Administrator
 *
 */
public class Employee {
	
	/**
	 * 主键id
	 */
	private Long id;
	
	/**
	 * 员工名称
	 */
	private String empName;
	
	/**
	 * 部门对象
	 */
	private Department department;

	public Long getId() {
		return id;
	}

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

	public String getEmpName() {
		return empName;
	}

	public void setEmpName(String empName) {
		this.empName = empName;
	}

	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}
}

 

对应的hibernate映射文件如下:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"D:\tools\hibernate\dtd\hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.xigua.domain">

	<class name="Department">

		<id name="id">
			<generator class="native" />
		</id>

		<property name="departName" column="depart_name" />
		
		<!-- 这个是一对多的配置,暂时不需要
		<set name="emps">
			<key column="depart_id"></key>
			<one-to-many class="Employee" />
		</set>
 		-->
	</class>

</hibernate-mapping>

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"D:\tools\hibernate\dtd\hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.xigua.domain">

	<class name="Employee">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="empName" column="emp_name"/>
		
		<!-- 这里是多对一配置,设置name跟 column属性即可,其余的属性配置都不是必须的 -->
		<many-to-one name="department" column="depart_id"/>
	</class>
	
</hibernate-mapping>

 

经过上述的配置之后,就将Employee跟Department进行了多对一绑定了。

可敲下面的代码验证:

package com.xigua.test;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.xigua.domain.Department;
import com.xigua.domain.Employee;
import com.xigua.utils.HibernateUtil;

public class Test1 {
	
	public static void main(String args[]) {
		
		save();
		query();
	}
	
	public static void save() {
		Session session = null;
		Transaction tx = null;
		try{
			session = HibernateUtil.getSession();
			tx = session.beginTransaction();
			
			Department depart = new Department();
			depart.setDepartName("dev");
			
			Employee emp1 = new Employee();
			emp1.setEmpName("xigua1");
			
			// 级联保存员工的部门
			emp1.setDepartment(depart);
			
			
			
			session.save(depart);
			session.save(emp1);
			
			tx.commit();
		}catch(Exception e) {
			if(tx != null) {
				tx.rollback();
			}
			throw e;
		}finally {
			if(session != null) {
				session.close();
			}
		}
	}
	
	public static void query() {
		Session session = null;
		try{
			session = HibernateUtil.getSession();
			
			Employee emp = (Employee) session.get(Employee.class, 1L);
			System.out.println(emp.getEmpName());
			
			// 级联查看员工对应的部门
			Department depart = emp.getDepartment();
			System.out.println(depart.getDepartName());
		}catch(Exception e) {
			throw e;
		}finally {
			if(session != null) {
				session.close();
			}
		}
	}

}

 

如果想在Department对象中也绑定一对多关系,则需要修改Department.java类跟对应的hibernate映射文件。

Department.java类中添加一个Set<Employee>集合对象,对应的hibernate文件中也配置一个<Set>标签,具体见下面的代码。

添加Set<Employee>集合对象后的Department.java类:

package com.xigua.domain;

import java.util.Set;


public class Department {
	
	/**
	 * 主键id
	 */
	private Long id;  
	
	/**
	 * 部门名称
	 */
	private String departName;
	
	/**
	 * set集合  存在该部门下的员工信息
	 */
	public Set<Employee> emps;

	public Long getId() {
		return id;
	}

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

	public String getDepartName() {
		return departName;
	}

	public void setDepartName(String departName) {
		this.departName = departName;
	}

	public Set<Employee> getEmps() {
		return emps;
	}

	public void setEmps(Set<Employee> emps) {
		this.emps = emps;
	}

}

 

对应的hibernate映射文件也添加<Set>标签:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"D:\tools\hibernate\dtd\hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.xigua.domain">

	<class name="Department">

		<id name="id">
			<generator class="native" />
		</id>

		<property name="departName" column="depart_name" />
		
		<!-- 这个是一对多的配置-->
		<set name="emps">
			<key column="depart_id"></key>
			<one-to-many class="Employee" />
		</set>
 		
	</class>

</hibernate-mapping>

 

以上就配置好了部门对象到员工对象的一对多关系。

可敲下面的代码进行验证:

package com.xigua.test;


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

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.xigua.domain.Department;
import com.xigua.domain.Employee;
import com.xigua.utils.HibernateUtil;

public class Test2 {
	
	public static void main(String args[]) {
		save();
		query();
	}

	public static void save() {
		Session session = null;
		Transaction tx = null;
		try{
			session = HibernateUtil.getSession();
			tx = session.beginTransaction();
			
			Employee emp1 = new Employee();
			emp1.setEmpName("xigua1");
			
			
			Employee emp2 = new Employee();
			emp2.setEmpName("xigua2");
			
			
			Department depart = new Department();
			depart.setDepartName("dev");
			// 级联保存employee对象
			Set<Employee> emps = new HashSet<Employee>();
			emps.add(emp1);
			emps.add(emp2);
			depart.setEmps(emps);
			
			session.save(emp1);
			session.save(emp2);
			session.save(depart);
			tx.commit();
		}catch(Exception e) {
			if(tx != null) {
				tx.rollback();
			}
			throw e;
		} finally {
			if(session != null) {
				session.close();
			}
		}
	}
	
	public static void query() {
		Session session = null;
		try{
			session = HibernateUtil.getSession();
			
			Department depart = (Department) session.get(Department.class, 1L);
			System.out.println(depart.getDepartName());
			
			// 级联获取部门员工数据
			Set<Employee> emps = depart.getEmps();
			if(emps != null && emps.size() > 0) {
				for(Employee emp : emps) {
					System.out.println(emp.getEmpName());
				}
			}
			
		} catch (Exception e) {
			throw e;
		} finally {
			if(session != null) {
				session.close();
			}
		}
	}
}

 

 

下面要说的是第二种多对一关系,即字表的外面不是主表的主键id的情况,这里我用订单主表跟订单产品明细表来举例。

先建好OrderMaster.java对象跟OrderDetail.java对象,通过orderNo(订单号)来关联。

package com.xigua.domain;

import java.util.Set;

public class OrderMaster {
	
	/**
	 * 订单主表主键id
	 */
	private Long id;
	
	/**
	 * 订单号
	 */
	private String orderNo;
	
	/**
	 * 一对多关系, 订单主表记录关联多个订单明细记录
	 */
	private Set<OrderDetail> orderDetails;

	public Long getId() {
		return id;
	}

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

	public String getOrderNo() {
		return orderNo;
	}

	public void setOrderNo(String orderNo) {
		this.orderNo = orderNo;
	}

	public Set<OrderDetail> getOrderDetails() {
		return orderDetails;
	}

	public void setOrderDetails(Set<OrderDetail> orderDetails) {
		this.orderDetails = orderDetails;
	}

	
}

 

package com.xigua.domain;

public class OrderDetail {
	
	/**
	 * 明细表主键id
	 */
	private Long id;
	
//	private String orderNo;  // 不需要定义了,定义了OrderMaster足够了
	
	/**
	 * 产品代码
	 */
	private String productCode;
	
	/**
	 * 产品数量
	 */
	private int productQty;
	
	/**
	 * 多对一关联,订单明细表记录关联的订单主表记录(每条订单明细记录都有对应的订单主表记录)
	 */
	private OrderMaster orderMaster;

	public Long getId() {
		return id;
	}

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

	public String getProductCode() {
		return productCode;
	}

	public void setProductCode(String productCode) {
		this.productCode = productCode;
	}

	

	public int getProductQty() {
		return productQty;
	}

	public void setProductQty(int productQty) {
		this.productQty = productQty;
	}

	public OrderMaster getOrderMaster() {
		return orderMaster;
	}

	public void setOrderMaster(OrderMaster orderMaster) {
		this.orderMaster = orderMaster;
	}
	
	

}

 

对应的映射文件如下:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"D:\tools\hibernate\dtd\hibernate-mapping-3.0.dtd">
<hibernate-mapping 
	package="com.xigua.domain">

	<class name="OrderMaster" table="order_master">
		
		<id name="id">
			<generator class="native"/>
		</id>
		
		<property name="orderNo" column="order_no"/>
		
		<!-- 一对多配置 -->
		<set name="orderDetails">
			<key column="order_no"></key>
			<one-to-many class="OrderDetail"/>
		</set>
		
	</class>
	
</hibernate-mapping>

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"D:\tools\hibernate\dtd\hibernate-mapping-3.0.dtd">
<hibernate-mapping 
	package="com.xigua.domain">

	<class name="OrderDetail" table="order_detail">
		
		<id name="id">
			<generator class="native"/>
		</id>
		
		<!-- 配置了多对一关系,明细对象中这个orderNo就不需要配置了, OrderDetail.java类中也不需要定义orderNo的属性字段了
		<property name="orderNo" column="order_no"/>
		 -->
		<property name="productCode" column="product_code"/>
		<property name="productQty" column="product_qty"/>
		
		<!-- 这里的多对一关联,由于字表的外键不是对应主表的主键id,而是orderNo属性,所以要添加property-ref="orderNo"的配置 这个orderNo指的是OrderMaster映射文件中的orderNo property -->
		<many-to-one name="orderMaster" column="order_no" property-ref="orderNo"/>
		
	</class>
	
</hibernate-mapping>

 

测试类代码如下:

package com.xigua.test;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.xigua.domain.OrderDetail;
import com.xigua.domain.OrderMaster;
import com.xigua.utils.HibernateUtil;

public class Test3 {
	
	public static void main(String args[]) {
		save();
		query();
	}

	public static void save() {
		Session session = null;
		Transaction tx = null;
		try{
			session = HibernateUtil.getSession();
			tx = session.beginTransaction();
			OrderMaster orderMaster = new OrderMaster();
			orderMaster.setOrderNo("201408100000001");
			
			OrderDetail orderDetail1 = new OrderDetail();
			orderDetail1.setProductCode("18013-02");
			orderDetail1.setProductQty(10);
			// 级联保存orderMaster
			orderDetail1.setOrderMaster(orderMaster);
			
			OrderDetail orderDetail2 = new OrderDetail();
			orderDetail2.setProductCode("18018-01");
			orderDetail2.setProductQty(5);
			// 级联保存orderMaster
			orderDetail2.setOrderMaster(orderMaster);
			
			session.save(orderDetail1);
			session.save(orderDetail2);
			session.save(orderMaster);
			
			tx.commit();
		}catch(Exception e) {
			if(tx != null) {
				tx.rollback();
			}
			throw e;
		}finally {
			if(session != null) {
				session.close();
			}
		}
	}
	
	public static void query() {
		Session session = null;
		
		try{
			session = HibernateUtil.getSession();
			OrderDetail orderDetail = (OrderDetail) session.get(OrderDetail.class, 1L);
			System.out.println(orderDetail.getProductCode() + "," + orderDetail.getProductQty());
			
			// 级联查询出OrderMaster
			OrderMaster orderMaster = orderDetail.getOrderMaster();
			System.out.println(orderMaster.getOrderNo());
		}catch(Exception e) {
			
			throw e;
		}finally {
			if(session != null) {
				session.close();
			}
		}
	}
}

 

package com.xigua.test;

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

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.xigua.domain.OrderDetail;
import com.xigua.domain.OrderMaster;
import com.xigua.utils.HibernateUtil;

public class Test4 {
	
	public static void main(String args[]) {
		save();
		query();
	}
	
	public static void save() {
		Session session = null;
		Transaction tx = null;
		try{
			session = HibernateUtil.getSession();
			tx = session.beginTransaction();
			OrderDetail orderDetail1 = new OrderDetail();
			orderDetail1.setProductCode("18013-02");
			orderDetail1.setProductQty(23);
			
			OrderDetail orderDetail2 = new OrderDetail();
			orderDetail2.setProductCode("18013-02");
			orderDetail2.setProductQty(23);
			
			Set<OrderDetail> orderDetails = new HashSet<OrderDetail>();
			orderDetails.add(orderDetail1);
			orderDetails.add(orderDetail2);
			
			OrderMaster orderMaster = new OrderMaster();
			orderMaster.setOrderNo("201408100000001");
			
			// 级联保存OrderDetail
			orderMaster.setOrderDetails(orderDetails);
			
			session.save(orderDetail1);
			session.save(orderDetail2);
			session.save(orderMaster);
			
			tx.commit();
		} catch (Exception e) {
			if(tx != null) {
				tx.rollback();
			}
			throw e;
		} finally {
			if(session != null) {
				session.close();
			}
		}
	}
	
	public static void query() {
		Session session = null;
		
		try{
			session = HibernateUtil.getSession();
			OrderMaster orderMaster = (OrderMaster) session.get(OrderMaster.class, 1L);
			System.out.println(orderMaster.getOrderNo());
			
			// 级联查询出OrderDetail
			Set<OrderDetail> orderDetails = orderMaster.getOrderDetails();
			if(orderDetails != null && orderDetails.size() > 0) {
				for(OrderDetail orderDetail : orderDetails) {
					System.out.println(orderDetail.getProductCode() + "," + orderDetail.getProductQty());
					
					// 结果验证,这里不能通过getOrderMaster()去拿订单主表信息 orderDetail.getOrderMaster() 是null值
					System.out.println(orderDetail.getOrderMaster());
				}
			}
		}catch(Exception e) {
			
			throw e;
		}finally {
			if(session != null) {
				session.close();
			}
		}
	}

}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值