一對(duì)多與多對(duì)一映射實(shí)現(xiàn)步驟
javaBean類
- 部門類
public class Dept {
private int deptId;
private String deptName;
private Set<Employee> emps;
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;
}
}
- 員工類
public class Employee {
private int empId;
private String empName;
private double salary;
// [多對(duì)一]員工與部門
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;
}
}
配置文件設(shè)置
- 部門的配置文件
<?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="com.flynn.one2many">
<class name="Dept" table="t_dept">
<id name="deptId">
<generator class="native"/>
</id>
<property name="deptName"></property>
<!--
一對(duì)多關(guān)聯(lián)映射的配置(通過部門管理到員工)
Dept 映射關(guān)鍵點(diǎn):
1. 指定 映射的集合屬性: "emps"
2. 集合屬性對(duì)應(yīng)的集合表: "t_employee"
3. 集合表的外鍵字段 "t_employee. dept_id"
4. 集合元素的類型
-->
<set name="emps" table="t_employee">
<key column="dept_id"></key>
<one-to-many class="Employee"></one-to-many>
</set>
</class>
</hibernate-mapping>
- 員工的配置文件
<?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="com.flynn.one2many">
<class name="Employee" table="t_employee">
<id name="empId">
<generator class="native"/>
</id>
<property name="empName" length="20"></property>
<property name="salary" type="double"></property>
<!--
多對(duì)一映射配置
Employee 映射關(guān)鍵點(diǎn):
1. 映射的部門屬性 : dept
2. 映射的部門對(duì)象拱层,對(duì)應(yīng)的外鍵字段: dept_id
3. 部門的類型
-->
<many-to-one name="dept" column="dept_id" class="Dept"></many-to-one>
</class>
</hibernate-mapping>
測(cè)試
@Test
public void testSaveDept(){
Session session = sessionFactory.openSession();
session.beginTransaction();
// 部門對(duì)象
Dept dept = new Dept();
dept.setDeptName("app developer");
// 員工對(duì)象
com.flynn.one2many.Employee emp_zs = new com.flynn.one2many.Employee();
emp_zs.setEmpName("zhangsan");
com.flynn.one2many.Employee emp_ls = new com.flynn.one2many.Employee();
emp_ls.setEmpName("lishi");
// 關(guān)系
Set<com.flynn.one2many.Employee> set = new HashSet<>();
set.add(emp_zs);
set.add(emp_ls);
dept.setEmps(set);
// 保存
session.save(emp_zs);
session.save(emp_ls);
session.save(dept); // 保存部門 部門下所有的員工
session.getTransaction().commit();
session.close();
/*
控制臺(tái)Hibernate的打印:
Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
Hibernate: insert into t_dept (deptName) values (?)
Hibernate: update t_employee set deptId=? where empId=?
Hibernate: update t_employee set deptId=? where empId=?
*/
}
// [推薦] 保存, 部員方[多的一方操作]
@Test
public void testSaveEmp(){
Session session = sessionFactory.openSession();
session.beginTransaction();
// 部門對(duì)象
Dept dept = new Dept();
dept.setDeptName("java developer");
// 員工對(duì)象
com.flynn.one2many.Employee emp_zs = new com.flynn.one2many.Employee();
emp_zs.setEmpName("zhangsan");
com.flynn.one2many.Employee emp_ls = new com.flynn.one2many.Employee();
emp_ls.setEmpName("lishi");
// 關(guān)系
emp_zs.setDept(dept);
emp_ls.setDept(dept);
// 保存
session.save(dept); // 先保存一的方法
session.save(emp_zs);
session.save(emp_ls); // 再保存多的一方, 關(guān)系會(huì)自動(dòng)維護(hù)(映射配置完)
session.getTransaction().commit();
session.close();
/*
Hibernate: insert into t_dept (deptName) values (?)
Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
*/
}
/**
* 獲取數(shù)據(jù)
*/
@Test
public void testDeptOrEmp(){
Session session = sessionFactory.openSession();
session.beginTransaction();
// 1.通過部門方, 獲取另外一方
Dept dept = (Dept) session.get(Dept.class, 1);
System.out.println(dept.getDeptName());
System.out.println(dept.getEmps()); // 懶加載
// 2.通過員工方, 獲取另外一方
com.flynn.one2many.Employee employee = (com.flynn.one2many.Employee) session.get(com.flynn.one2many.Employee.class, 1);
System.out.println(employee.getEmpName());
System.out.println(employee.getDept());
}
在一對(duì)多與多對(duì)一的關(guān)聯(lián)關(guān)系中, 保存數(shù)據(jù)最好的通過多的一方來維護(hù)關(guān)系, 這樣可以減少update語句的生成, 從而提高 hibernate 的執(zhí)行效率 !
配置一對(duì)多與多對(duì)一 , 這種叫"雙向關(guān)聯(lián)"
只配置一對(duì)多 , 叫"單項(xiàng)一對(duì)多"
只配置多對(duì)一, 叫"單項(xiàng)多對(duì)一"
注意:
- 配置了哪一方, 哪一方才有維護(hù)關(guān)聯(lián)關(guān)系的權(quán)限!
Inverse屬性
Inverse屬性,是在維護(hù)關(guān)聯(lián)關(guān)系的時(shí)候起作用的态贤。
表示控制權(quán)是否轉(zhuǎn)移舱呻。(在一的一方起作用)
Inverse , 控制反轉(zhuǎn)醋火。
Inverse = false 不反轉(zhuǎn)悠汽; 當(dāng)前方有控制權(quán)
True 控制反轉(zhuǎn); 當(dāng)前方?jīng)]有控制權(quán)
維護(hù)關(guān)聯(lián)關(guān)系中芥驳,是否設(shè)置inverse屬性:
- 保存數(shù)據(jù)
有影響柿冲。
如果設(shè)置控制反轉(zhuǎn),即inverse=true, 然后通過部門方維護(hù)關(guān)聯(lián)關(guān)系。在保存部門的時(shí)候兆旬,同時(shí)保存員工假抄, 數(shù)據(jù)會(huì)保存,但關(guān)聯(lián)關(guān)系不會(huì)維護(hù)丽猬。即外鍵字段為NULL
image.png
- 保存數(shù)據(jù)
- 獲取數(shù)據(jù)
無宿饱。
- 獲取數(shù)據(jù)
-
- 解除關(guān)聯(lián)關(guān)系?
有影響脚祟。
- inverse=false谬以, 可以解除關(guān)聯(lián)
- inverse=true, 當(dāng)前方(部門)沒有控制權(quán)由桌,不能解除關(guān)聯(lián)關(guān)系 (不會(huì)生成update語句,也不會(huì)報(bào)錯(cuò))
- 解除關(guān)聯(lián)關(guān)系?
-
- 刪除數(shù)據(jù)對(duì)關(guān)聯(lián)關(guān)系的影響为黎?
有影響。
- inverse=false, 有控制權(quán)行您, 可以刪除铭乾。先清空外鍵引用,再刪除數(shù)據(jù)娃循。
- inverse=true, 沒有控制權(quán): 如果刪除的記錄有被外鍵引用炕檩,會(huì)報(bào)錯(cuò),違反主外鍵引用約束捌斧! 如果刪除的記錄沒有被引用捧书,可以直接刪除事扭。
- 刪除數(shù)據(jù)對(duì)關(guān)聯(lián)關(guān)系的影響为黎?
cascade 屬性
cascade 表示級(jí)聯(lián)操作 【可以設(shè)置到一的一方或多的一方】
- none 不級(jí)聯(lián)操作陆盘, 默認(rèn)值
- save-update 級(jí)聯(lián)保存或更新
- delete 級(jí)聯(lián)刪除
- save-update,delete 級(jí)聯(lián)保存、更新绘雁、刪除
- all 同上洞难。級(jí)聯(lián)保存舆吮、更新、刪除