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

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

[MySQL表的增删改查-进阶]

🌈个人主页:努力学编程’ ⛅个人推荐: c语言从初阶到进阶 JavaEE详解 数据结构 ⚡学好数据结构,刷题刻不容缓:点击一起刷题 🌙心灵鸡汤:总有人要赢,为什么不能是我呢 💻💻💻数据库约束 🔭🔭🔭约束类型 not null: 指示某列不能存储 NULL 值unique: 保证某列的每行必须有唯一的值default: 规定没有给列赋值时的默认值.primary key:

滚雪球学Java(87):Java事务处理:JDBC的ACID属性与实战技巧!真有两下子!

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE啦,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~ 🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!! 环境说明:Windows 10

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

Flutter 进阶:绘制加载动画

绘制加载动画:由小圆组成的大圆 1. 定义 LoadingScreen 类2. 实现 _LoadingScreenState 类3. 定义 LoadingPainter 类4. 总结 实现加载动画 我们需要定义两个类:LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态,而 LoadingPainter 则负责绘制动画。

从0到1,AI我来了- (7)AI应用-ComfyUI-II(进阶)

上篇comfyUI 入门 ,了解了TA是个啥,这篇,我们通过ComfyUI 及其相关Lora 模型,生成一些更惊艳的图片。这篇主要了解这些内容:         1、哪里获取模型?         2、实践如何画一个美女?         3、附录:               1)相关SD(稳定扩散模型的组成部分)               2)模型放置目录(重要)

java学习,进阶,提升

http://how2j.cn/k/hutool/hutool-brief/1930.html?p=73689

【408DS算法题】039进阶-判断图中路径是否存在

Index 题目分析实现总结 题目 对于给定的图G,设计函数实现判断G中是否含有从start结点到stop结点的路径。 分析实现 对于图的路径的存在性判断,有两种做法:(本文的实现均基于邻接矩阵存储方式的图) 1.图的BFS BFS的思路相对比较直观——从起始结点出发进行层次遍历,遍历过程中遇到结点i就表示存在路径start->i,故只需判断每个结点i是否就是stop

java面试常见问题之Hibernate总结

1  Hibernate的检索方式 Ø  导航对象图检索(根据已经加载的对象,导航到其他对象。) Ø  OID检索(按照对象的OID来检索对象。) Ø  HQL检索(使用面向对象的HQL查询语言。) Ø  QBC检索(使用QBC(Qurey By Criteria)API来检索对象。 QBC/QBE离线/在线) Ø  本地SQL检索(使用本地数据库的SQL查询语句。) 包括Hibern