Hibernate之一对多与多对一映射
来源:互联网 发布:淘宝门头制作 编辑:程序博客网 时间:2024/04/29 19:02
一,概述
需求:员工与部门,一个部门有多个员工,多个员工可以在同一个部门,这是典型的一对多与多对一关系.这种关系在Hibernate中怎样映射呢?(Hibernate中这种映射叫关联映射)
二,设计JavaBean
1)部门
package com.bighuan.b_one2many;import java.util.HashSet;import java.util.Set;public class Dept { private int deptId; private String deptName; /** * 一对多,一个部门对应多个员工 */ private Set<Employee> emps=new HashSet<Employee>(); public Dept(){ } 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; } }
2)员工
package com.bighuan.b_one2many;public class Employee {private int empId;private String empName;private double salary;/** * 多对一:多个员工对应一个部门 */private Dept dept;public Employee(){}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;}}
三,JavaBean对应的映射文件
1)Dept.hbm.xml
<?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.bighuan.b_one2many"><!-- 对象与表对应 --><class name="Dept" table="t_dept"><!-- 属性与字段对应 --><!-- 主键 ,映射--><id name="deptId"><generator class="native" /></id><!-- 属性映射 --><property name="deptName" length="20"></property><!-- 一对多关联映射配置 (通过部门管理到员工)Dept 映射关键点:1. 指定 映射的集合属性: "emps"2. 集合属性对应的集合表: "t_employee"3. 集合表的外键字段 "t_employee. dept_id"4. 集合元素的类型dept_id需要和Employ.hbm.xml中<many-to-one>中的column一样 --><set name="emps" table="t_employee"><!-- table="t_employee" 可以省略 --><key column="dept_id"></key><one-to-many class="Employee"/></set></class></hibernate-mapping>
2)Employee.hbm.xml
<?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.bighuan.b_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><!-- 多对一映射配置Employee 映射关键点:1. 映射的部门属性 : dept2. 映射的部门属性,对应的外键字段: dept_id3. 部门的类型many-to-one可以做到将一个对象映射生成一个外键字段 --> <many-to-one name="dept" column="dept_id" class="Dept"></many-to-one></class></hibernate-mapping>(hibernate.cfg.xml在前面几篇关于Hibernate的博客里都有介绍,不粘贴了)
四,测试
1)插入数据
package com.bighuan.b_one2many;import java.util.HashSet;import java.util.Set;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.junit.Test;import com.bighuan.a_collection.User;public class App {private static SessionFactory sf;static {sf = new Configuration().configure().addClass(Dept.class).addClass(Employee.class)//测试时用.buildSessionFactory();}//保存:部门方,一的一方进行操作@Testpublic void testSave() throws Exception {// 获得sessionorg.hibernate.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();}//保存:员工方,多的一方进行操作,推荐使用多的一方进行保存数据@Testpublic void testSave2() throws Exception {// 获得sessionorg.hibernate.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();}}2)既可以通过部门方来保存数据,也可以通过员工方来保存数据.通过部门方保存数据执行了如下sql语句:
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 dept_id=? where empId=?Hibernate: update t_employee set dept_id=? where empId=?而通过员工方保存数据则执行了更少的sql语句,如下:
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 (?, ?, ?)通过对比可以得知,通过多的一方来保存数据可以减少update语句,因此开发中建议通过多的一方来保存数据,减少sql语句的执行,提高Hibernate效率.
五,inverse与cascade属性
1)Inverse属性,是在维护关联关系的时候起作用的, 表示控制权是否转移。(在一的一方起作用)
Inverse , 控制反转;Inverse = false 不反转;当前方有控制权;inverse= true 控制反转,当前方没有控制权.
2)维护关联关系中,是否设置inverse属性:
a. 保存数据
有影响。
如果设置控制反转,即inverse=true, 然后通过部门方维护关联关系。在保存部门的时候,同时保存员工, 数据会保存,但关联关系不会维护。即外键字段为NULL.
b. 获取数据
无影响.
c. 解除关联关系?
有影响。
inverse=false,可以解除关联;inverse=true,前方(部门)没有控制权,不能解除关联关系(不会生成update语句,也不会报错).
d. 删除数据对关联关系的影响?
有影响。
inverse=false, 有控制权, 可以删除。先清空外键引用,再删除数据。
inverse=true, 没有控制权: 如果删除的记录有被外键引用,会报错,违反主外键引用约束! 如果删除的记录没有被引用,可以直接删除。
3)cascade 属性
cascade 表示级联操作 【可以设置到一的一方或多的一方】
none 不级联操作, 默认值
save-update 级联保存或更新
delete 级联删除
save-update,delete 级联保存、更新、删除
all 同上。级联保存、更新、删除
六,总结
配置一对多与多对一,这种叫“双向关联”;只配置一对多,叫“单项一对多”;只配置多对一, 叫“单项多对一”.
注意:配置了哪一方,哪一方才有维护关联关系的权限!
- Hibernate之一对多与多对一映射
- Hibernate之一对多和多对一映射笔记
- Hibernate框架学习-映射关系之一对多与多对一
- SSH框架之Hibernate的关联映射之一对多、多对一映射
- Hibernate关联映射之一对多、多对多映射
- hibernate多对一映射
- Hibernate 多对一映射
- 【Hibernate】多对一映射
- hibernate多对一映射
- Hibernate---一对多映射与多对一映射
- Hibernate之一对多映射关系小结
- Hibernate之一对多关联映射
- hibernate映射关系之一对多
- Hibernate之一对多关联映射
- Hibernate基础之一对多映射
- hibernate初探之一对多映射
- hibernate的映射关系之一对多
- Hibernate初探之一对多映射
- 对象指针
- Factorial Trailing Zeroes
- 利用输入法输入汉字,如何统计字数
- Java事务处理全解析(八)——分布式事务入门例子(Spring+JTA+Atomikos+Hibernate+JMS)
- Android 开发环境配置
- Hibernate之一对多与多对一映射
- centos7安装php7
- 机器学习—随机森林算法
- 博客迁移至简书
- Http协议学习
- 站在风口的猪也会飞,背后推手是谁?
- docker容器启动后修改启动命令参数
- Node.js模块小记之--util
- Mysql 函数