您的位置:首页 > 其它

Hibernate一对多双向关联映射

2014-06-16 20:04 585 查看
Department部门和Employee员工是一对多的关系,再多的一端会有一个外键来维护关系,即多的一端是关系的维护端,少的一端为关系的被维护端。

部门实体Department.java:

/**
 * 部门和员工的关系为一对多,多的一端为关系的维护端,
 * 关系的维护端来负责外键的更新,少的一端无权更新外键字段。
 * @author Liao
 */
public class Department {

	/* 部门Id */
	private Integer id;
	/* 部门名称 */
	private String name;
	/* 部门和员工的关系(一对多) */
	private Set<Employee> employees;

	public Integer getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Set<Employee> getEmployees() {
		return employees;
	}

	public void setEmployees(Set<Employee> employees) {
		this.employees = employees;
	}

}


员工实体Employee.java:


public class Employee {

	/* 员工ID */
	private Integer id;
	/* 员工名称 */
	private String name;
	/* 员工和部门的关系(多对一) */
	private Department department;

	public Integer getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.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">
<!-- package表示实体类的包名 -->        
<hibernate-mapping package="com.lixue.bean">
	<!-- class结点的name表示实体的类名,table表示实体映射到数据库中table的名称 -->
	<class name="Department" table="t_department">
		<id name="id" column="did">
			<!-- 自增长 -->
			<generator class="native"/>
		</id>
		<property name="name" column="dname"/>
		
		<!-- 部门和员工的关系(一对多) -->
		<set name="employees" inverse="true">
			<key column="dept_id"/><!-- 表示在多的一端加一个字段 -->
			<one-to-many class="Employee"/>
		</set>
	</class>
</hibernate-mapping>
注:

1.一对多双向关联映射的方式:在一的一端的集合上采用<key>标签,在多的一端加入一个外键。

2.在多的一端采用<many-to-one>标签

3.inverse属性:inverse属性可以用在一对多和多对多双向关联上,inverse属性默认为false,为false时表示本端可以维护关系,如果inverse为true,则本端不能维护关系,会交给另外一端维护关系,本端失效(在一对多的关联映射上我们通常让多的一端维护关系,让一的一端失效)。

4.inverse和cascade:inverse是控制方向上的反转,只影响存储,cascade是操作是的连锁反应。



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">
<!-- package表示实体类的包名 -->        
<hibernate-mapping package="com.lixue.bean">
	<!-- class结点的name表示实体的类名,table表示实体映射到数据库中table的名称 -->
	<class name="Employee" table="t_employee">
		<id name="id" column="eid">
			<!-- 自增长 -->
			<generator class="native"/>
		</id>
		<property name="name" column="ename"/>
		<!-- 设置Employee和Department的关系column表示和Department.hbm.xml文件的外键映射要一致 -->
		<many-to-one name="department" column="dept_id"/>
	</class>
</hibernate-mapping>
注:Employee为多的一端,作为关系的维护端,通过一个外键即dept_id来维护。

测试类:

public class One2ManyTest {

	public static void main(String[] args) {
		
		Session session = HibernateUtils.getSession();
		Transaction transaction = session.beginTransaction();
		
		/*创建部门并设置属性*/
		Department department = new Department();
		department.setName("开发部");
		session.save(department);
		
		/*创建员工并设置属性*/
		Employee employee = new Employee();
		employee.setName("习近平");
		employee.setDepartment(department);
		
		session.save(employee);
		
		transaction.commit();
	}
}
注:我这里只是随便测试了一下,并未关闭Session和Transaction。

注:一对多和多对一的区别在于维护的关系不同:

1.多对一维护的关系是:多指向一的关系,有了此关系,在加载多的时候可以将一加载上来。

2.一对多维护关系的是:一指向多的关系,有了此关系,在加载一的时候可以将多加载上来。

一对多关联的缺陷:

1.因为多的一端Employee不知道Department的存在(也就是Employee没有维护Department的关系),所以在保存Employee的时候关系字段dept_id是为null的,如果将该字段设为非空,那么连数据都存不进去。

2.另外因为Employee不维护关系,而Department维护关系,Department就会发出多余的update语句,来保证Department和Employee有关系,这样加载Department的时候才可以把对应的Employee加载上来。

注:一对多单向关联有很大缺陷,所以采用一对多双向关联映射的目的主要是为了解决一对多单向关联的缺陷,而不是需求驱动的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: