hibernate笔记(二)
小编:管理员 380阅读 2022.09.14
目标:
关联映射(hibernate映射)
1. 集合映射
2. 一对多与多对一映射 (重点)
3. 多对多映射
4. inverse/lazy/cascade
1. 集合映射开发流程:
需求分析/数据库设计、项目设计/ 编码/测试/实施部署上线/验收
需求:
用户购买, 填写地址!
数据库:
代码:
// javabean设计
public class User {
private int userId;
private String userName;
// 一个用户,对应的多个地址
private Set |
---|
|
// 保存set
@Test
public void testSaveSet() throws Exception {
Session session = sf.openSession();
session.beginTransaction();
//-- 保存
Set |
问题:
集合映射,映射的集合元素,都是普通的类型, 能否为对象类型?
2. 关联映射需求1:
部门与员工
一个部门有多个员工; 【一对多】
多个员工,属于一个部门 【多对一】
需求2:
项目与开发员工
一个项目,有多个开发人员!
一个开发人员,参与多个项目! 【多对多】
多对一映射与一对多代码需求:员工与部门
数据库:
设计javabean封装:
映射:
public class Dept {
private int deptId;
private String deptName;
// 【一对多】 部门对应的多个员工
private Set |
---|
public class Employee { private int empId; private String empName; private double salary; // 【多对一】员工与部门 private Dept dept; Dept.hbm.xml |
|
Employee.hbm.xml |
|
测试 |
public class App { private static SessionFactory sf; static { sf = new Configuration() .configure() .addClass(Dept.class) .addClass(Employee.class) // 测试时候使用 .buildSessionFactory(); } // 保存, 部门方 【一的一方法操作】 @Test public void save() { Session session = sf.openSession(); session.beginTransaction(); // 部门对象 Dept dept = new Dept(); dept.setDeptName("应用开发部"); // 员工对象 Employee emp_zs = new Employee(); emp_zs.setEmpName("张三"); Employee emp_ls = new Employee(); emp_ls.setEmpName("李四"); // 关系 dept.getEmps().add(emp_zs); dept.getEmps().add(emp_ls); // 保存 session.save(emp_zs); session.save(emp_ls); session.save(dept); // 保存部门,部门下所有的员工 session.getTransaction().commit(); session.close(); /* * 结果 * 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=? 维护员工引用的部门的id Hibernate: update t_employee set deptId=? where empId=? */ } // 【推荐】 保存, 部员方 【多的一方法操作】 @Test public void save2() { Session session = sf.openSession(); session.beginTransaction(); // 部门对象 Dept dept = new Dept(); dept.setDeptName("综合部"); // 员工对象 Employee emp_zs = new Employee(); emp_zs.setEmpName("张三"); Employee emp_ls = new Employee(); emp_ls.setEmpName("李四"); // 关系 emp_zs.setDept(dept); emp_ls.setDept(dept); // 保存 session.save(dept); // 先保存一的方法 session.save(emp_zs); session.save(emp_ls);// 再保存多的一方,关系回自动维护(映射配置完) 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 (?, ?, ?) 少生成2条update sql */ } } |
在一对多与多对一的关联关系中,保存数据最好的通过多的一方来维护关系,这样可以减少update语句的生成,从而提高hibernate的执行效率!
配置一对多与多对一,这种叫“双向关联”
只配置一对多, 叫“单项一对多”
只配置多对一, 叫“单项多对一”
注意:
配置了哪一方,哪一方才有维护关联关系的权限!
Inverse属性Inverse属性,是在维护关联关系的时候起作用的。
表示控制权是否转移。(在一的一方起作用)
Inverse , 控制反转。
Inverse = false 不反转; 当前方有控制权
True 控制反转; 当前方没有控制权
维护关联关系中,是否设置inverse属性:
1. 保存数据
有影响。
如果设置控制反转,即inverse=true, 然后通过部门方维护关联关系。在保存部门的时候,同时保存员工, 数据会保存,但关联关系不会维护。即外键字段为NULL
2. 获取数据
无。
3. 解除关联关系?
有影响。
inverse=false, 可以解除关联
inverse=true, 当前方(部门)没有控制权,不能解除关联关系
(不会生成update语句,也不会报错)
4. 删除数据对关联关系的影响?
有影响。
inverse=false, 有控制权, 可以删除。先清空外键引用,再删除数据。
inverse=true, 没有控制权: 如果删除的记录有被外键引用,会报错,违反主外键引用约束! 如果删除的记录没有被引用,可以直接删除。
cascade 属性cascade 表示级联操作 【可以设置到一的一方或多的一方】
none 不级联操作, 默认值
save-update 级联保存或更新
delete 级联删除
save-update,delete 级联保存、更新、删除
all 同上。级联保存、更新、删除
hibernate常见面试题: inverse与cascade区别?
多对多映射需求:项目与开发人员
Project Developer
电商系统
曹吉
王春
OA系统
王春
老张
数据库
代码
/**
* 开发人员
*
* @author Jie.Yuan
*
*/
public class Developer {
private int d_id;
private String d_name;
// 开发人员,参数的多个项目
private Set |
---|
/**
* 项目
*
* @author Jie.Yuan
*
*/
public class Project {
private int prj_id;
private String prj_name;
// 项目下的多个员工
private Set |
Project.hbm.xml |
|
Developer.hbm.xml |
|
设置inverse属性,在多对多种维护关联关系的影响?
1) 保存数据
有影响。
inverse=false ,有控制权,可以维护关联关系; 保存数据的时候会把对象关系插入中间表;
inverse=true, 没有控制权, 不会往中间表插入数据。
2) 获取数据
无。
3) 解除关系
// 有影响。
// inverse=false ,有控制权, 解除关系就是删除中间表的数据。
// inverse=true, 没有控制权,不能解除关系。
4) 删除数据
有影响。
// inverse=false, 有控制权。 先删除中间表数据,再删除自身。
// inverse=true, 没有控制权。 如果删除的数据有被引用,会报错! 否则,才可以删除
相关推荐
- 经典笔试题-JDBC及Hibernate篇 五、JDBC 及Hibernate:(共12 题:基础10 道,中等难度2 道)110、数据库,比如100 用户同时来访,要采取什么技术解决?【基础】 答:可采用连接池。111、什么是ORM?【基础】 答:对象关系映射(Object—Relational Mapping,简称ORM)是一种为了解决面向对象…
- 3DMAX提示和技巧 本主题标识使用 Civil View 的一些重要提示和技巧。常规使用屏幕分辨率至少为 1280x1024 的 Civil View。低于此分辨率时,一些面板将占用过多屏幕空间。 将视口设置为线框显示以达到最佳性能。 要尽可能简化用户界面,请在单个视口中工作并关闭 3ds Max 命令面…