Hibernate入门基础-单向一对多关联

单向·1-n关联只需从1的一端可以访问n的一端.

在实际开发里面,关于一对多和多对一,有一个设计原则:尽量避免去使用一对多这种关系,而应该多使用多对一这种关系.但有时候不可避免的,例如:订单和订单项就是一对多的这种关系,一个订单里面有多个订单项,在显示订单的时候一定要显示多方的数据的,即订单项,这时候我们就必须设计这种关系了.如果你没有设计这种关系,这时候从数据库里面找出订单的基本信息,人家一看订单,只能看到订单的基本信息,不能看到订单项,这是不行的。如果这时候不可避免的要设计这种关系(一对多这种关系),并且订单项有上千万条的数据,那么千万不能直接将其找出来,一定要采用分页的方式去找。

首先两个实体类,一个部门类,一个职工类: 

Department.java

package hibernate.model.o2m;

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

//部门(one)
public class Department {
	private Integer id;
	private String name;
	private Set<Employee> employeeSet = new HashSet<Employee>();
//此处省略get,set方法
}

Employee.java

package hibernate.model.o2m;
//员工(many)
public class Employee {

	private Integer id;
	private String name;
//此处省略get,set方法
}

Employee类的映射文件:Employee.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="hibernate.model.o2m">
<class name="Employee" table="e_emp">
	<id name="id" column="e_id">
	  <!-- 设置成increment之后,会从数据库中查找主键id最大的值,然后+1进行存储 -->
	  <generator class="increment"></generator> 
	</id>
	<property name="name" column="e_name"></property>
</class>
</hibernate-mapping>

Department.hbm.xml映射文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="hibernate.model.o2m">
	<class name="Department" table="d_dept">
		<id name="id" column="d_id">
			<!-- 设置为native之后,主键会按照本来的顺序进行增长(比如之前11但是删除了,现在就从12开始) -->
			<generator class="native"></generator>
		</id>
		<property name="name" column="d_name"></property>
		
		 <!-- 
            inverse:默认为false, 指关联关系的控制权由自己来维护
            inverse设置为true的时候,就说明关联在多的那一方被维护 (一般设置在多的一方去维护,效率会跟高一点)
           
        -->
		<set name="employeeSet"  cascade="all" lazy="false">
			<key column="d_id"></key>
			<one-to-many class="Employee" />
		</set>

	</class>

</hibernate-mapping>

One-To-Many测试类

package hibernate.model.o2m;


import java.util.Set;


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


import xh.util.HibernateUtil;
import hibernate.model.o2m.Department;
//单向一对多
public class O2mTest {
	private Session session;


	public O2mTest() {
		session = HibernateUtil.getInstance().getSession();
	}


	// 保存
	@Test
	public void o2mTest() {


		session.beginTransaction();
		Employee emp1 = new Employee();
		emp1.setName("员工1");
		Employee emp2 = new Employee();
		emp2.setName("员工2");


		Department dept = new Department();
		dept.setName("财务部");


		dept.getEmployeeSet().add(emp1);
		dept.getEmployeeSet().add(emp2);
		try {
			//用了级联
			session.save(dept);
			/*session.save(emp1);
			session.save(emp2);*/
			session.beginTransaction().commit();
			session.close();
		} catch (Exception e) {
			session.beginTransaction().rollback();
		}
		


	}


	@Test
	public void testQuery() {
		Department department = (Department) session.get(Department.class, 1);
		Set<Employee> set = department.getEmployeeSet();
		System.out.print("部门Id为1的员工:");
		for (Employee employee2 : set) {
			System.out.print(employee2.getName()+",");
		}
	}
}


单向一对多:实体之间的关系由"一"的一端加载"多"的一端,关系由"一"的一端持有"多"的一端的集合.在我们加载"一"的时候把多也加载进来了,也就是部门中维护职工的集合。我们可以根据部门找到属于这些部门的所有职工.但不能根据职工找到属于它所属的部门

为什么会有5条sql语句,进行insert之后为什么还要update呢? 
因为单向一对多关系是在”一”的一方维护数据,多的一方Employee并不知道有Department的存在。所以在保存Employee的时候,关系字段did是为null的。如果把did字段设置为非空,则无法保存数据。 
因为Employee不维护关系,而是由Department来维护关系,则在对Department进行操作的时候,就会发出多余的update语句,去维持Department与Employee的关系,这样加载Department的时候才会把该Department对应的职工加载进来。所以会多两条udate语句。这样的效率是非常低的。

为了提高效率,我们一般会采用双向一对多关联的方式。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值