部门和员工 一个部门多个员工,一个员工只属于一个部门。
单向多对一关联关系
- 1.编写Dept和Emp持久化类
- 2.使用
建立EMP表的外键DEPYNO和dept属性之间的映射 - 3.验证对象持久化方法
package com.pojo;
import java.io.Serializable;
public class Emp implements Serializable {
private Integer empNo;//员工编号
private String empName;//员工姓名
private String job;//员工职位
private double salary;//员工薪水
private Department department;//所属部门
public Integer getEmpNo() {
return empNo;
}
public void setEmpNo(Integer empNo) {
this.empNo = empNo;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
public Emp() {
}
public Emp(Integer empNo, String empName, String job, double salary, Department department) {
this.empNo = empNo;
this.empName = empName;
this.job = job;
this.salary = salary;
this.department = department;
}
@Override
public String toString() {
return "Emp{" +
"empNo=" + empNo +
", empName='" + empName + '\'' +
", job='" + job + '\'' +
", salary=" + salary +
", department=" + department +
'}';
}
}
package com.pojo;
import java.io.Serializable;
public class Department implements Serializable {
private Byte deptNo;//部门编号
private String deptName;//部门名称
private String location;//部门地址
public Byte getDeptNo() {
return deptNo;
}
public void setDeptNo(Byte deptNo) {
this.deptNo = deptNo;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public Department() {
}
public Department(Byte deptNo, String deptName, String location) {
this.deptNo = deptNo;
this.deptName = deptName;
this.location = location;
}
@Override
public String toString() {
return "Department{" +
"deptNo=" + deptNo +
", deptName='" + deptName + '\'' +
", location='" + location + '\'' +
'}';
}
}
元素建立emp表的外键deotNo和department属性之间的映射
- name:设定持久化类的属性名,这里是Emp类的department属性
- column:设定持久化类的属性对应表的外键,这里是emp表的外键
- class:设定持久化类的属性类型,设定department属性为Dept类型
/**
* 存储员工
*/
public void save(Emp emp) {
this.getCurrentSession().save(emp);
}
public void save() {
Emp emp = new Emp();
emp.setEmpNo(10002);
emp.setEmpName("张三");
emp.setJob("研发");
emp.setSalary(13000.50);
Department department=new Department();
department.setDeptNo((byte)10);
emp.setDepartment(department);
empBiz.save(emp);
}
Hibernate:
select
department_.deptNo,
department_.deptName as deptName0_,
department_.location as location0_
from
project.Department department_
where
department_.deptNo=?
Hibernate:
insert
into
project.Emp
(empName, job, salary, deptNo, empNo)
values
(?, ?, ?, ?, ?)
总结
- 先查询外键的部门编号是否存在,如果存在插入信息,如果不存在,抛出异常报错
Caused by: java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails (project
.emp
, CONSTRAINTFK110A816FF5875
FOREIGN KEY (deptNo
) REFERENCESdepartment
(deptNo
))
双向一对多关联关系
- 1.在Department类中增加一个集合类型的emps属性
- 2.使用
元素映射emps属性 - 3.验证双向一对多关联元素对象持久化方法
package com.pojo;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
public class Department implements Serializable {
private Byte deptNo;//部门编号
private String deptName;//部门名称
private String location;//部门地址
private Set emps=new HashSet<>();//部门员工集合
public Byte getDeptNo() {
return deptNo;
}
public void setDeptNo(Byte deptNo) {
this.deptNo = deptNo;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public Set getEmps() {
return emps;
}
public void setEmps(Set emps) {
this.emps = emps;
}
public Department() {
}
public Department(Byte deptNo, String deptName, String location, Set emps) {
this.deptNo = deptNo;
this.deptName = deptName;
this.location = location;
this.emps = emps;
}
@Override
public String toString() {
return "Department{" +
"deptNo=" + deptNo +
", deptName='" + deptName + '\'' +
", location='" + location + '\'' +
", emps=" + emps +
'}';
}
}
元素表明Department类的emps属性是Set集合
- name:设定持久化类的属性名,为Department类的emps属性
- cascade:保存删除Dept对象的同时级联保存或删除与Dept对象关联的Emp对象
元素表明emp表通过外键deptNo参考department表
- column:设定与所关联的持久化类相对应的表的外键,为emp表的deptNo字段
元素表明emps集合存放的是一组Emp对象
cascade属性的取值
- 1.none 当Session操作当前对象时,忽略其他关联对象,他是cascade属性默认值
- 2.save-update当通过Session的save(),update()及saveOrUpdate()方法来保存或跟新当前对象时,级联保存所有关联的瞬时状态的对象,并且级联更新所有关联的游离对象
- 3.delete当通过Session的delete()方法删除当前对象时,会级联删除所有关联对象
- 4.包含save-update,delete方法
级联插入
public void save(Department department) {
this.getCurrentSession().save(department);
}
//创建一个部门
Department department = new Department();
department.setDeptNo((byte) 16);
department.setDeptName("研发部");
department.setLocation("广州");
//创建一个员工
Emp emp=new Emp();
emp.setEmpName("李四");
emp.setEmpNo(1008);
emp.setJob("研发");
emp.setSalary(19500.50);
//建立Dept对象和Emp对象双向关联关系
emp.setDepartment(department);
department.getEmps().add(emp);
departmentBiz.saveDept(department);
Hibernate:
select
emp_.empNo,
emp_.empName as empName1_,
emp_.job as job1_,
emp_.salary as salary1_,
emp_.deptNo as deptNo1_
from
project.Emp emp_
where
emp_.empNo=?
Hibernate:
insert
into
project.Department
(deptName, location, deptNo)
values
(?, ?, ?)
Hibernate:
insert
into
project.Emp
(empName, job, salary, deptNo, empNo)
values
(?, ?, ?, ?, ?)
Hibernate:
update
project.Emp
set
deptNo=?
where
empNo=?
总结
首先因为主键生成策列是assigned先查询是否存在该OID的emp对象,之后插入Dept对象,再插入Emp对象,最后更新Emp表的外键与Dept表同步。
级联删除
public void delete(Department department) {
this.getCurrentSession().delete(department);
}
public void delete() {
Department department = departmentBiz.getDept((byte) 89);
departmentBiz.deleteDept(department);
}
Hibernate:
select
department0_.deptNo as deptNo0_0_,
department0_.deptName as deptName0_0_,
department0_.location as location0_0_
from
project.Department department0_
where
department0_.deptNo=?
Hibernate:
select
department_.deptNo,
department_.deptName as deptName0_,
department_.location as location0_
from
project.Department department_
where
department_.deptNo=?
Hibernate:
select
emps0_.deptNo as deptNo0_1_,
emps0_.empNo as empNo1_,
emps0_.empNo as empNo1_0_,
emps0_.empName as empName1_0_,
emps0_.job as job1_0_,
emps0_.salary as salary1_0_,
emps0_.deptNo as deptNo1_0_
from
project.Emp emps0_
where
emps0_.deptNo=?
Hibernate:
update
project.Emp
set
deptNo=null
where
deptNo=?
Hibernate:
delete
from
project.Emp
where
empNo=?
Hibernate:
delete
from
project.Department
where
deptNo=?
总结
首先主键生成策列是assigned根据部门编号查询了两次部门信息,再根据部门编号查询了部门员工,根据部门编号更新员工表外键置为null,随后根据员工编号删除员工信息,最后根据部门编号删除部门
inverse属性指定了关联关系中的方向,默认是false。在关联关系中,inverse="false"的一方是主动方,主动方会负责维护关联关系。例如部门一方会主动执行update语句即update emp set deptNo=? where empno=?用来维护外键的取值。但是 emp.setDepartment(department);
设定了正确的关联关系,该语句实际上是多余的,执行多余的update语句会影响应用的性能。
Hibernate:
select
emp_.empNo,
emp_.empName as empName1_,
emp_.job as job1_,
emp_.salary as salary1_,
emp_.deptNo as deptNo1_
from
project.Emp emp_
where
emp_.empNo=?
Hibernate:
insert
into
project.Department
(deptName, location, deptNo)
values
(?, ?, ?)
Hibernate:
insert
into
project.Emp
(empName, job, salary, deptNo, empNo)
values
(?, ?, ?, ?, ?)