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

在一方记住了多方,在多方也记住了一方 ,双向管理,我们这样设计就是双向的关联,在实际开发里面,这种双向的关联是不推荐使用的!而且一对多这种关系最好就不要设计,即不要在一方记住多方,如果你设计了,在找出一方的数据时就要取出多方的数据,如果对方的数据超多的话,很容易导致内存溢出.

   虽然在实际开发里面,一对多/多对一双向关联不推荐使用,但是我们还是应该有所了解的。

Department.java

package hibernate.model.o2mDouble;

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>();
}
Employee.java
package hibernate.model.o2mDouble;
//员工(many)
public class Employee {

	private Integer id;
	private String name;
	private Department department;
}

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.o2mDouble">
	<class name="Department" table="dept">
		<id name="id" column="did">
			<!-- 设置为native之后,主键会按照本来的顺序进行增长(比如之前11但是删除了,现在就从12开始) -->
			<generator class="native"></generator>
		</id>
		<property name="name" column="dname"></property>
       <!-- employees属性,Set集合,表达的是本类与Employee的一对多的关系
            class属性:关联的实体类型
            key子元素:对方表中的外键列(多方的哪个表)
            inverse属性:
                默认为false,表示本方维护关联关系。
                如果为true,表示本方不维护关联关系。
           cascade="all" -->
		<set name="employeeSet"   lazy="false"  inverse="true">
			<key column="deptid"></key>
			<one-to-many class="Employee" />
		</set>

	</class>

</hibernate-mapping>

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.o2mDouble">
<class name="Employee" table="emp">
	<id name="id" column="eid">
	  <!-- 设置成increment之后,会从数据库中查找主键id最大的值,然后+1进行存储 -->
	  <generator class="increment"></generator> 
	</id>
	<property name="name" column="ename"></property>
	<many-to-one name="department" class="Department" column="deptid"></many-to-one>
</class>
</hibernate-mapping>

在hibernate.cfg.xml注册加载

<mapping resource="hibernate/model/o2mDouble/Department.hbm.xml" />
		<mapping resource="hibernate/model/o2mDouble/Employee.hbm.xml" />

O2mDouble测试类

package hibernate.model.o2mDouble;

import java.util.Set;

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

import xh.util.HibernateUtil;

//单向一对多
public class O2mDouble {
	private Session session;

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

	// 保存
	@Test
	public void o2mTest() {
		
		
		try {
			session.beginTransaction();
			Department dept = new Department();
			dept.setName("财务部");

			Employee emp1 = new Employee();
			emp1.setName("员工1");
			emp1.setDepartment(dept);
			
			Employee emp2 = new Employee();
			emp2.setName("员工2");
			emp2.setDepartment(dept);

			
			dept.getEmployeeSet().add(emp1);
			dept.getEmployeeSet().add(emp2);
			session.save(dept);
			session.save(emp1);
			session.save(emp2);
			session.beginTransaction().commit();
			session.close();
		} catch (Exception e) {
			session.beginTransaction().rollback();
		}

	}

	@Test
	public void testQuery() {
		//多方获取
		Employee employee = (Employee) session.get(Employee.class, 1);
		String e_name = employee.getName();
		String d_name = employee.getDepartment().getName();
		System.out.println("员工:"+e_name+",部门:"+d_name);
		System.out.println("--------------------");
		Department dept = (Department) session.get(Department.class, 1);
		String name = dept.getName();
		Set<Employee> set = dept.getEmployeeSet();
		for (Employee employee2 : set) {
			System.out.println("员工:"+employee2.getName()+",部门:"+name);
		}
		
	}
}

结论

  1. 在映射一对多的双向关联关系时,应该在one方把inverse属性设为true,这可以提高性能
  2. 当删除双向关联的关系时,也应该修改关联两端的对象的相应属性:
department.getEmployees().clear(); // 清空
employee.setDepartment(null);

    3.只有集合标记(set/map/list/array/bag)才有inverse属性。

    4.维护关联关系是指设置外键列的值(设置有效值或是null值).

    5. 因为是双向操作,所以保存任何一方都能成功,但是推荐保存”一”的一方,并在”一”的一方交出控制权,这样会提高效率

6.


结论是:无论是从哪一方获取数据,都能获取到关联对方的数据。 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值