`
xigua366
  • 浏览: 102448 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

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
2
分享到:
评论

相关推荐

    hibernate一对多项目

    1. **配置一对多关系**: - 在实体类中,我们需要定义一个集合类型的属性,比如`List&lt;Order&gt;`,表示一个用户可以有多个订单,使用`@OneToMany`注解标记这个属性。该注解接受一个`mappedBy`参数,指定多的一方在关联...

    Hibernate ORM - 一对多双向关联关系

    描述部分为空,但我们可以根据标题推测,这篇博客可能详细解释了如何在Hibernate中配置和管理这种一对多双向关联,包括XML配置、注解方式,以及如何在代码中进行操作和查询。 **Hibernate ORM简介** Hibernate是一...

    Hibernate的配置详解

    在本篇中,我们将深入探讨Hibernate的配置,特别是涉及一对一、一对多和多对多关系的配置。 首先,配置过程始于`Configuration`接口。这个接口用于设置Hibernate所需的配置信息,如数据源、连接参数等,并根据配置...

    Hibernate 配置各种数据库

    下面是一个使用 properties 文件配置 Hibernate 连接数据库的示例: hibernate.connection.driver_class = org.hsqldb.jdbcDriver hibernate.connection.username = sa hibernate.connection.password = hibernate....

    hibernate一级和二级缓存配置与详解

    本篇将深入探讨Hibernate的一级缓存和二级缓存,以及查询缓存的配置和使用。 ### 一级缓存 一级缓存是Hibernate默认提供的缓存,它是Session级别的,每个Hibernate Session都有一个私有的、本地的一级缓存。当我们...

    hibernate配置文件详解

    Hibernate 的配置文件是其核心组件之一,用于定义 Hibernate 的运行期参数。下面我们将详细介绍 Hibernate 配置文件的结构和内容。 一、hibernate.cfg.xml 文件 hibernate.cfg.xml 文件是 Hibernate 的基本配置...

    hibernate基于主外键的一对多/多对一关联

    总结起来,Hibernate中的一对多/多对一关联是通过主外键映射来实现的,通过注解和配置文件定义实体间的关联关系,利用懒加载或立即加载策略控制数据获取,同时要注意双向关联的维护和级联操作的设置,以确保数据的...

    spring和hibernate整合的优化配置

    - **性能调优**:通过对Hibernate配置参数进行调优,比如设置合理的缓存策略、调整查询参数等,可以进一步提升系统的响应速度。 #### 四、总结 Spring与Hibernate的整合是现代Java企业级应用开发中的常见模式。...

    hibernateJar包及配置文件

    2. Hibernate配置文件(hibernate.cfg.xml): - 数据库连接配置:包括数据库URL、用户名、密码、驱动类名等,这些信息定义了应用程序如何连接到数据库。 - 映射文件引用:通过`&lt;mapping resource=""/&gt;`标签,指定...

    Hibernate程序的配置文件

    5. **缓存配置**:Hibernate支持一级缓存(Session级别)和二级缓存(SessionFactory级别)。开发者可以根据需求选择是否开启及配置二级缓存,例如,可以使用EhCache或Infinispan。 6. **事务管理**:Hibernate支持...

    Hibernate配置文件hibernate.cfg.xml中配置信息详解

    Hibernate配置文件hibernate.cfg.xml中配置信息详解!

    Hibernate基本配置演示

    这篇教程将深入讲解Hibernate的基本配置过程,确保你能顺利搭建并运行一个简单的Hibernate项目。 **一、Hibernate概述** Hibernate是一个开源的ORM框架,它的主要功能是将Java对象与数据库表进行映射,从而避免了...

    Hibernate核心配置文件对照表

    这些配置选项只是`hibernate.properties`中的一部分,实际使用时可能还需要根据项目需求配置更多的参数。理解并正确配置这些参数对于优化Hibernate性能、保证数据一致性以及简化开发流程至关重要。通过调整这些配置...

    Hibernate连接SQLite配置说明和方言代码

    2.2、打开此文件,将“&lt;property name="hibernate.connection.url"&gt;jdbc:sqlite:D:/EGSDatabase.egsdata”一行中的数据库文件("D:/EGSDatabase.egsdata")修改为合适的数据库文件。 注:附件包含了...

    Hibernate 一对一,一对多,多对多例子

    “Hibernate 一对一,一对多,多对多例子” 指的是使用Hibernate框架实现数据库中不同关联关系的示例。Hibernate是一个Java持久化框架,它提供了对象关系映射(ORM)功能,使得开发人员可以方便地在Java对象和关系...

    JAVA 使用hibernate配置实例

    通过这个实例,你将掌握在Java项目中使用Hibernate的基本流程,无论是普通Java工程还是Maven工程,都能轻松实现对数据库的操作。在实际开发中,你可以根据项目需求进一步优化配置,比如加入事务管理、查询优化等,以...

    配置hibernate数据源

    3. 创建Hibernate配置文件。通常该文件命名为hibernate.cfg.xml,并放置在项目的src目录下。配置文件中需要声明以下关键内容: - 数据库方言(Dialect):指定Hibernate针对哪种数据库优化其SQL语句。 - 连接...

    oracle的hibernate配置文件

    `hibernate1.cfg.xml`是Hibernate配置的核心文件,它定义了数据源、连接池、持久化类、缓存策略等关键信息。以下将逐个解析这些重要部分。 1. 数据源配置: 在`hibernate1.cfg.xml`中,首先需要配置数据源。对于...

    Hibernate自动生成配置文件

    ### Hibernate自动生成配置文件详解 #### 一、Hibernate与自动生成配置文件的重要性 ...因此,掌握并熟练运用MyEclipse中Hibernate配置文件的自动生成功能,对任何级别的Java开发者来说都是一项极为有价值的技能。

Global site tag (gtag.js) - Google Analytics