视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Hibernate关联映射
2020-11-09 16:31:34 责编:小采
文档


集合映射 开发流程: 需求分析/数据库设计、项目设计/ 编码/测试/实施部署上线/验收需求: 用户购买, 填写地址! // javabean设计 public class User { private int userId; private String userName; // 一个用户,对应的多个地址 private Set String addre

集合映射

开发流程:
 需求分析/数据库设计、项目设计/ 编码/测试/实施部署上线/验收

需求:
 用户购买, 填写地址!
// javabean设计
public class User {

 private int userId;
 private String userName;
 // 一个用户,对应的多个地址
 private Set address;
 private List addressList = new ArrayList(); 
 //private String[] addressArray; // 映射方式和list一样 
 private Map addressMap = new HashMap();

}






 
 
 
  
 

 
 
 
 
 

 
 
 
 
 
 

 
 
 
 
 
  
 
 // 测试程序
 // 保存set
 @Test
 public void testSaveSet() throws Exception {
 Session session = sf.openSession();
 session.beginTransaction();

 //-- 保存
 Set addressSet = new HashSet();
 addressSet.add("广州");
 addressSet.add("深圳");
 // 用户对象
 User user = new User();
 user.setUserName("Jack");
 user.setAddress(addressSet);

 // 保存
 session.save(user);

 session.getTransaction().commit();
 session.close();
 }

 // 保存list/map
 @Test
 public void testSaveList() throws Exception {
 Session session = sf.openSession();
 session.beginTransaction();
 User user = new User();
 user.setUserName("Tom");
// // 用户对象 -- list
// user.getAddressList().add("广州");
// user.getAddressList().add("深圳");
// // 保存
// session.save(user);

 // 用户对象 -- Map
 user.getAddressMap().put("A0001", "广州");
 user.getAddressMap().put("A0002", "深圳");

 // 保存
 session.save(user);

 session.getTransaction().commit();
 session.close();
 }
问题:
 集合映射,映射的集合元素,都是普通的类型, 能否为对象类型?

关联映射

需求1:
 部门与员工
 一个部门有多个员工; 【一对多】
 多个员工,属于一个部门 【多对一】
需求2:
 项目与开发员工
 一个项目,有多个开发人员!
 一个开发人员,参与多个项目! 【多对多】

多对一映射与一对多

1. 需求:员工与部门
2. 数据库:
3. 设计javabean封装:
4. 映射:

JavaBean

public class Dept {

 private int deptId;
 private String deptName;
 // 【一对多】 部门对应的多个员工
 private Set emps = new HashSet();
} 
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 同上。级联保存、更新、删除

多对多映射

需求:项目与开发人员
 Project Developer
 电商系统
 曹吉
 王春
 OA系统
 王春
 老张

JavaBean

public class Developer {
 private int d_id;
 private String d_name;
 // 开发人员,参数的多个项目
 private Set projects = new HashSet();
}
public class Project {
 private int prj_id;
 private String prj_name;
 // 项目下的多个员工
 private Set developers = new HashSet();
}

Project.hbm.xml






 
 
 
  
 
 
 
 
 
  
 

Developer.hbm.xml






 
 
 
  
 

 
 
 
 
  
 

维护关联关系

设置inverse属性,在多对多种维护关联关系的影响?

1) 保存数据
 有影响。
 inverse=false ,有控制权,可以维护关联关系; 保存数据的时候会把对象关系插入中间表;
 inverse=true, 没有控制权, 不会往中间表插入数据。

2) 获取数据
 无。

3) 解除关系
 有影响。
 inverse=false ,有控制权, 解除关系就是删除中间表的数据。
 inverse=true, 没有控制权,不能解除关系。

4) 删除数据
 有影响。
 inverse=false, 有控制权。 先删除中间表数据,再删除自身。
 inverse=true, 没有控制权。 如果删除的数据有被引用,会报错! 否则,才可以删除

下载本文
显示全文
专题