hibernate进阶之一对多和inverse属性

2024-04-16 13:32

本文主要是介绍hibernate进阶之一对多和inverse属性,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

dept.java

package cn.itcast.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 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;}
}

Employee.java

package cn.itcast.b_one2Many;public class Employee {private int empId;private String empName;private double salary;// 【多对一】员工与部门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;}
}
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="cn.itcast.b_one2Many"><class name="Dept" table="t_dept"><id name="deptId"><generator class="native"></generator></id>	<property name="deptName" length="20"></property><!-- 一对多关联映射配置  (通过部门管理到员工)Dept 映射关键点:1.  指定 映射的集合属性: "emps"2.  集合属性对应的集合表: "t_employee"3.  集合表的外键字段   "t_employee. dept_id"4.  集合元素的类型inverse=false  set集合映射的默认值; 表示有控制权--><set name="emps" cascade="save-update,delete" table="t_employee" inverse="false">   <!-- table="t_employee" --><key column="dept_id"></key><one-to-many class="Employee"/></set> </class>
</hibernate-mapping>

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="cn.itcast.b_one2Many"><class name="Employee" table="t_employee"><id name="empId"><generator class="native"></generator></id>	<property name="empName" length="20"></property><property name="salary" type="double"></property><!-- 多对一映射配置Employee 映射关键点:1.  映射的部门属性  :  dept2.  映射的部门属性,对应的外键字段: dept_id3.  部门的类型--><many-to-one name="dept" column="dept_id" class="Dept"></many-to-one> </class>
</hibernate-mapping>

App1_save.java

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;public class App1_save {private static SessionFactory sf;static {sf = new Configuration().configure().addClass(Dept.class)   .addClass(Employee.class)   // 测试时候使用.buildSessionFactory();}// 保存, 部门方 【一的一方法操作】@Testpublic 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();/*结果* inverse = falseHibernate: 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=?    维护员工引用的部门的idHibernate: update t_employee set deptId=? where empId=?结果* inverse = trueHibernate: 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 (?)*/}// 【推荐】 保存, 部员方 【多的一方法操作】@Testpublic 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();/*结果:无论inverse=true还是falseHibernate: 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 (?, ?, ?)*/}
}  

----public void save() {...}执行分析

一方Dept.hbm.xmlSet集合inverse = true

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 (?)


一方Dept.hbm.xmlSet集合Inverse=false

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=?//deptId值有更新,inverse=false有关,具有控制权

Hibernate: update t_employee set dept_id=? where empId=?//deptId值有更新


public void save2() {...}执行结果分析

一方Dept.hbm.xmlSet集合inverse = false

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 (?, ?, ?)


-----Inverse是hibernate双向关系中的基本概念。inverse的真正作用就是指定由哪一方来维护之间的关联关系。当一方中指定了“inverse=false”(默认),那么那一

方(主控方)就有责任负责之间的关联关系,说白了就是hibernate如何生成Sql来维护关联的记录!

 Hibernate仅仅按照主控方对象的状态的变化来同步更新数据库。按照原来的映射文件,dept.getEmps().add(emp_zs);即主控方对象的状态发生了改变,因此数据库

会跟着对象状态的变化来同步更新数据库;而emp_zs.setDept(dept);,即被控方对象的状态发生了改变,它是不能触发对象和数据库的同步更新的。


这篇关于hibernate进阶之一对多和inverse属性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/908919

相关文章

从基础到进阶详解Python条件判断的实用指南

《从基础到进阶详解Python条件判断的实用指南》本文将通过15个实战案例,带你大家掌握条件判断的核心技巧,并从基础语法到高级应用一网打尽,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录​引言:条件判断为何如此重要一、基础语法:三行代码构建决策系统二、多条件分支:elif的魔法三、

Python进阶之列表推导式的10个核心技巧

《Python进阶之列表推导式的10个核心技巧》在Python编程中,列表推导式(ListComprehension)是提升代码效率的瑞士军刀,本文将通过真实场景案例,揭示列表推导式的进阶用法,希望对... 目录一、基础语法重构:理解推导式的底层逻辑二、嵌套循环:破解多维数据处理难题三、条件表达式:实现分支

基于Python编写自动化邮件发送程序(进阶版)

《基于Python编写自动化邮件发送程序(进阶版)》在数字化时代,自动化邮件发送功能已成为企业和个人提升工作效率的重要工具,本文将使用Python编写一个简单的自动化邮件发送程序,希望对大家有所帮助... 目录理解SMTP协议基础配置开发环境构建邮件发送函数核心逻辑实现完整发送流程添加附件支持功能实现htm

Python如何调用另一个类的方法和属性

《Python如何调用另一个类的方法和属性》在Python面向对象编程中,类与类之间的交互是非常常见的场景,本文将详细介绍在Python中一个类如何调用另一个类的方法和属性,大家可以根据需要进行选择... 目录一、前言二、基本调用方式通过实例化调用通过类继承调用三、高级调用方式通过组合方式调用通过类方法/静

基于Python实现进阶版PDF合并/拆分工具

《基于Python实现进阶版PDF合并/拆分工具》在数字化时代,PDF文件已成为日常工作和学习中不可或缺的一部分,本文将详细介绍一款简单易用的PDF工具,帮助用户轻松完成PDF文件的合并与拆分操作... 目录工具概述环境准备界面说明合并PDF文件拆分PDF文件高级技巧常见问题完整源代码总结在数字化时代,PD

javaSE类和对象进阶用法举例详解

《javaSE类和对象进阶用法举例详解》JavaSE的面向对象编程是软件开发中的基石,它通过类和对象的概念,实现了代码的模块化、可复用性和灵活性,:本文主要介绍javaSE类和对象进阶用法的相关资... 目录前言一、封装1.访问限定符2.包2.1包的概念2.2导入包2.3自定义包2.4常见的包二、stati

C语言进阶(预处理命令详解)

《C语言进阶(预处理命令详解)》文章讲解了宏定义规范、头文件包含方式及条件编译应用,强调带参宏需加括号避免计算错误,头文件应声明函数原型以便主函数调用,条件编译通过宏定义控制代码编译,适用于测试与模块... 目录1.宏定义1.1不带参宏1.2带参宏2.头文件的包含2.1头文件中的内容2.2工程结构3.条件编

spring中的@MapperScan注解属性解析

《spring中的@MapperScan注解属性解析》@MapperScan是Spring集成MyBatis时自动扫描Mapper接口的注解,简化配置并支持多数据源,通过属性控制扫描路径和过滤条件,利... 目录一、核心功能与作用二、注解属性解析三、底层实现原理四、使用场景与最佳实践五、注意事项与常见问题六

从入门到进阶讲解Python自动化Playwright实战指南

《从入门到进阶讲解Python自动化Playwright实战指南》Playwright是针对Python语言的纯自动化工具,它可以通过单个API自动执行Chromium,Firefox和WebKit... 目录Playwright 简介核心优势安装步骤观点与案例结合Playwright 核心功能从零开始学习

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.