Hibernate5入门(四)映射之一对多(多对一)

学习笔记,为了加强记忆和深入理解在此记录备忘。如有错误和理解不当之处,还望指正。万分感谢!

另外,实例和内容有些是参照网络其他博文,如有侵权可联系删除。

参考博文:https://www.cnblogs.com/biehongli/p/6561690.html

学习重点:

1、学习Hibernate一对多和多对一的配置

set元素和many-to-one元素的配置

2、学习关联关系及保存顺序

关系维护:数据最好通过多的一方维护,这样可以减少update sql;

保存顺序:保存的顺序最好是先保存一的一方再保存多的一方,提高效率,少执行update sql语句


 以员工和部门为例:

一个部门包含多个员工【一对多映射】

扫描二维码关注公众号,回复: 2468066 查看本文章

多个员工属于一个部门【多对一映射】

一、关于单向和双向

关于单向和双向区别

单向主表更新,从表更新。从表更新,主表不管。主表可以查询到从表内容,从表不能查询主表内容

双向更新一张表,另一张表中与之相关联的数据都进行更新,两张表都可以相互查询

关于单向和双向实体类的区别(一对多)

单向:部门实体类引入了员工对象的集合属性 ;员工实体类正常

双向:部门实体类引入了员工对象的集合属性 ;员工实体类引入老师的对象;

关于单向和双向映射文件的区别(一对多)

单向:部门对象的映射引入one-to-many元素配置;员工对象的映射文件正常无需额外配置

双向:部门对象的映射引入one-to-many元素配置;员工对象的映射文件引入many-to-one元素配置

双向是在单向的基础上增加配置,一对多双向反过来就是多对一双向。以下示例为双向一对多

单向和双向区别实例
一对多 单向(一) 双向(一) 单向(多) 双向(多)
实体类

除了自己的属性外增加多的一方对象集合

private Set<Employee> emps;

除了自己的属性外增加了多方对象集合

private Set<Employee> emps;

只有自己的属性,没有其他

除了自己的属性外,增加了一方的对象

private Dept dept;

映射文件

增加了set元素

<set name="emps" 

      table="t_employee">
  <key column="deptId" />
  <one-to-many class="Employee" />
</set>

增加了set元素

<set name="emps" 

      table="t_employee">
  <key column="deptId" />
  <one-to-many class="Employee" />
</set>

只有自己的映射关系,没有其他

增加many-to-one元素

<many-to-one                  
  name="dept" 
  column="deptId" 
  class="Dept" />

二、一对多(多对一)

部门Dept实体类

package demo.entity;

import java.util.Set;

/*
* 关键点是通过部门实体类维护到员工的实体类
*/
public class Dept {

	private int deptId;// 部门编号
	private String deptName;// 部门名称

	private Set<Employee> emps;// 部门对应多个员工,即一对多的关系
	// private Set<Employee> emps = new HashSet<>();//方便赋值,这里可以直接创建实例化

	public int getDeptId() {
		return deptId;
	}

	public void setDeptId(int deptId) {
		this.deptId = deptId;
	}

	public String getDeptName() {
		return deptName;
	}

	public void setDeptName(String deptName) {
		this.deptName = deptName;
	}

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

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

}

Employee实体类

package demo.entity;

public class Employee {

	private int empId;// 员工的编号
	private String empName;// 员工的名称
	private double salary;// 员工的薪资

	private Dept dept;// 员工和部门的关系

	public int getEmpId() {
		return empId;
	}

	public void setEmpId(int empId) {
		this.empId = empId;
	}

	public String getEmpName() {
		return empName;
	}

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

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public Dept getDept() {
		return dept;
	}

	public void setDept(Dept dept) {
		this.dept = dept;
	}

}

Dept映射文件

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="demo.entity">
	<class name="Dept" table="t_dept">
		<!-- 第一写主键映射 -->
		<id name="deptId" column="deptId">
			<generator class="native" />
		</id>
		<!-- 第二写其他字段映射 -->
		<property name="deptName" column="deptName" 
			length="20"	type="string" />
		<!-- 
			第三写其他映射,比如这里的set集合映射,set集合映射主要有以下几点:
				1 实体类申明的集合属性属性(name)
				2 集合属性对应的表(table)
				3 指定集合表的外键字段名称(key中的column)
				4 集合对象对应的实体类(noe-to-many中的class)
		-->
		<set name="emps" table="t_employee">
			<!--column指定了员工表的外键字段名称 -->
			<key column="deptId"></key>
			<!-- class由于上面已经写了包名,这里直接使用即可 -->
			<one-to-many class="Employee" />
		</set>
	</class>
</hibernate-mapping>

Employee映射文件

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="demo.entiey">
	<class name="Employee" table="employee">
		<!-- 主键映射 -->
		<id name="empId" column="empId">
			<generator class="native"></generator>
		</id>
		<!-- 其他字段映射 -->
		<property name="empName" column="empName" length="20" type="string"/>
		<property name="salary" column="salary" type="double" />
		<!-- 
			多对一的映射配置:
			name是实体类中申明的属性;
			column外键字段名称;
			class对应的部门实体类;
		-->
		<many-to-one name="dept" column="deptId" class="Dept" />
	</class>

</hibernate-mapping>

测试

package demo.test;

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

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import demo.entity.Dept;
import demo.entity.Employee;

class JunitTest {
	private Configuration configuration = new Configuration().configure();
	private SessionFactory sFactory = configuration.buildSessionFactory();
	private Session session = null;
	private Transaction transaction = null;
	@BeforeEach
	void setUp() throws Exception {
		session = sFactory.openSession();
		transaction = session.beginTransaction();
	}

	@AfterEach
	void tearDown() throws Exception {
		transaction.commit();
		session.close();
	}

	@Test
	void testSave() {
		// 实例化部门和员工
		Dept dept1 = new Dept();
		dept1.setDeptName("人事部");
		Dept dept2 = new Dept();
		dept2.setDeptName("技术部");		
		Employee employee1 = new Employee();
		employee1.setEmpName("员工1");
		employee1.setSalary(1000);
		Employee employee2 = new Employee();
		employee2.setEmpName("员工2");
		employee2.setSalary(2000);
		Employee employee3 = new Employee();
		employee3.setEmpName("员工3");
		employee3.setSalary(3000);
		Employee employee4 = new Employee();
		employee4.setEmpName("员工4");
		employee4.setSalary(4000);		
		
		// 通过部门(一)设置员工(多)【不推荐】 
		Set<Employee> employees = new HashSet<>();
		employees.add(employee1);
		employees.add(employee2);
		dept1.setEmps(employees);
		// 通过员工(多)设置部门(一)【推介】
		employee3.setDept(dept2);
		employee4.setDept(dept2);
		
		// 数据最好通过多的一方维护,这样可以减少update sql
		// 保存的顺序最好是先保存一的一方再保存多的一方,提高效率,少执行update sql语句
		// 【不推介】
		session.save(employee1);
		session.save(employee2);
		session.save(dept1);
		// 【推介】
		session.save(dept2);
		session.save(employee3);
		session.save(employee4);
		
	}

}

把映射文件加入到配置文件中

  <mapping resource="demo/entity/Dept.hbm.xml"/>
  <mapping resource="demo/entity/Employee.hbm.xml"/>

 

猜你喜欢

转载自blog.csdn.net/u012423685/article/details/81169191