11. Hibernate 持久化对象的各种状态

1. 前言

本节课和大家聊聊持久化对象的 3 种状态。通过本节课程,你将了解到:

  • 持久化对象的 3 种状态;
  • 什么是对象持久化能力。

2. 持久化对象的状态

程序运行期间的数据都是存储在内存中。内存具有临时性。程序结束、计算机挂机…… 内存中的数据将不复存在。

重要的数据,需要使用持久化技术将数据保存到永久性设备上。Hibernate 能够通过 PO(持久化对象) 将数据持久化到数据库。

Hibernate 对 PO 进行操作期间,PO 本身会发生一系列的状态变化。

2.1 瞬时状态(Transient)

分析一段保存数据的实例:

使用 Hibernate 保存数据之前,须先在程序中创建一个名为 stu 的 PO

Student stu=new Student("PO对象的瞬时状态", "男");  

此 PO 在程序运行的内存中存在,数据库中没有。PO 此时处于瞬时状态 (Transient)

瞬时状态下的 PO 特征如下:

  • 程序中有、数据库中没有此对象的相关信息;
  • 对象的标识性属性(对应表中主键的那个属性) 为空;
  • 如果不使用 Session 对象的相关方法进行数据库请求操作,程序退出时瞬时状态的对象信息会丢失。

2.2 持久化状态( Persistent )

创建 PO 后,使用 Session 的相关方法,如 save() 方法向数据库提交保存请求:

Student stu=new Student("PO对象的瞬时状态", "男");
session.save(stu);  

此时 PO 在程序中有,数据库中也有,状态便由瞬时状态转变成为持久化状态(Persistent)

持久化状态下的 PO 有如下几个特征:

  • 程序、数据库中都有 PO 的信息;
  • 对象的标识属性的值为数据库中对应记录的主键值;
  • 持久化状态最大的特点是 PO 处于 Session 生命周期之内。此状态下的 PO 具有持久化能力。

2.3 游离状态(Detached)

PO 的持久化状态一直维持到 Session 对象关闭。如果 Session 对象关闭了,此 PO 的状态将由持久化状态转变成游离状态 (Detached)

游离状态时 PO 的特点:

  • 程序、数据库都有 PO 的信息;
  • 但是,此状态下的 PO 不具有持久化能力。

PO 不会一直停留在某一个状态上,PO 随时可以在 3 种状态之间进行切换。

从上图可看出,PO 的 3 种状态之间的相互演变都是通过调用 Session 对象的相关方法实现的。

由此看来,Session 对象被称为持久化容器是有道理的。

由上图可知,处于瞬时状态游离状态的对象才有可能被 JVM 垃圾回收器回收

3. 对象持久化能力

知道了 PO 的 3 种状态。自然会问:不同状态下的对象对实际操作有什么实际指导意义?

3 种状态中,持久化状态的意义最大,如果 PO 处于持久化状态,此时 PO 就具有持久化能力。

所谓对象持久化能力,通俗理解:

程序中的数据发生变化,会自动同步到数据库中。

演示一段数据更新实例,更新之前先查询数据:

try {transaction = session.beginTransaction();//查询学生Student stu=(Student)session.load(Student.class, new Integer(2));//修改学生信息//执行更新操作transaction.commit();
} catch (Exception e) {transaction.rollback();
} finally {session.close();
}  

通过 Session 的 get() 方法查询出来的 stu 对象,此时就处于持久化状态。

在” 修改学生信息 “的注释下添加一行代码:

stu.setStuName("持久化状态就是这么牛"); 

不需要调用 Session 中的任何其它方法,执行代码,程序中修改的数据立即同步到数据库中。

这就是持久化状态的特点:通过 PO 自动同步程序与数据库中的数据

所谓对象持久化能力本质上还是 Session 给的。
Session 记录对象是否处于持久化状态,并充当后台靠山。处于持久状态的对象与数据库之间的数据同步,只是不需要 Session 显示调用。

除了 get()、load()方法。save()、update()、saveOrUpdate()、persis()、megre() 方法都可称为持久化方法。

调用这些方法后,能让对象进入持久化状态,Session 记录并且默默维持 PO 中数据与数据库中数据的同步。

3.1 save() 和 persist() 方法

saveOrUpdate() 方法很好理解,是 save() 和 update() 方法的综合简化版,内在本质没改变。

save() 和 persist() 方法有细节上的区别。
save() 方法原型:

public Serializable save(Object object);

上一段 save () 方法的测试实例:

try {Student  stu = new Student("save()方法", "男");Serializable  stuId = session.save(stu);System.out.println("----------输出学生编号Id---------");System.out.println(stu.getStuId());System.out.println(stuId);System.out.println("----------事务在后面-------"); transaction = session.beginTransaction();transaction.commit();
} catch (Exception e) {transaction.rollback();  
} finally {session.close();
}  

输出结果:

Hibernate: insert intoStudent(stuName, stuPassword, stuPic, stuSex) values(?, ?, ?, ?)
----------输出学生编号Id---------
40
40
----------事务在后面------- 

结果即结论:

Save() 方法可以在事务之外执行;
有一个关键点需要引起重视:

无论是在事务之内还是事务之外,save() 方法都会向数据库发送了一条 Sql 语句请求,控制台输出结果是一样的。

但是:

  • 如果程序中 Hibernate 不显示发送事务提交指令,数据会回滚(丢失);
  • 只有当数据库系统接收到程序中发送过来的事务提交指令后,才会真正意义上保存。

很好理解,因为事务是交给 Hibernate 管理的,数据库接收到插入指令后,在没有明确事务提交指令之前,只会把数据缓存在内存中。
也就是说,虽然 save() 方法看起来不依赖事务就可插入数据,但,没有事务组件的指令,最后也是虚行一场。

persist() 方法原型:

public void persist(Object object);  

上一段 persist() 测试实例:

try {Student stu = new Student("persist()方法", "男");session.persist(stu);System.out.println("----------输出学生编号Id---------");System.out.println(stu.getStuId());System.out.println("----------事务在后面-------");transaction = session.beginTransaction(); System.out.println("-------------事务提交---------------");transaction.commit();System.out.println(stu.getStuId());
} catch (Exception e) {transaction.rollback();
} finally {session.close();
}

输出结果:

----------输出学生编号Id---------
null
----------事务在后面-------
-------------事务提交---------------
Hibernate: insert intoStudent(stuName, stuPassword, stuPic, stuSex) values(?, ?, ?, ?)
39 

persist() 方法只有当事务提交后,才会发送 Sql 请求,数据直接写入数据库,方法本身没有返回值。

save() 和 persist() 方法区别:

  • 在事务之内调用时,两者区别不大;事务之外,区别明显。
  • save() 返回主键值,persist() 方法没有返回值;
  • persist() 完全依赖事务组件,否则不会提交 Sql 请求;
  • persist() 方法除了可进行 save 操作,还可以进行 update 操作。

3.2 merge() 方法

方法原型:

 public Object  merge(Object object);  

merge() 方法和 persist() 方法类似, 区别在于:

  • merge() 方法接收一个 PO 作为参数,创建并返回此 PO 的副本对象;
  • 此副本对象具有对象持久化能力。这一点是 merge() 方法与其他方法最大的不同。

上一段实例:

try{transaction = session.beginTransaction();//查询出来的stu具有持久化能力Student stu = (Student) session.get(Student.class, new Integer(2));    //转stu对象持久化状态转变成游离状态session.clear();//stu_对象具有持久化能力Student stu_ = (Student) session.merge(stu);//这个操作不能同步到数据库stu.setStuName("我已经不具有持久化能力");//这个操作能同步到数据库stu_.setStuName("我具有持久化能力");transaction.commit();
} catch(Exception e) {transaction.rollback();
} finally {session.close();
}  

merge() 方法返回的 stu 对象的副本 stu_,此对象具有持久化能力。执行下面代码,数据能同步到数据库中。

stu_.setStuName("我具有持久化能力");  

Session 中提供的每一个方法都有其实际意义。

特别是 merge() 方法,既可以保护原对象中的数据不被污染,又能行使数据库同步操作。

在很多场景里都会有这个需求。

4. 小结

本节课程讲解 PO 对象的 3 种状态,以及 3 种状态之间的转化方式。了解处于持久化状态的 PO 具有持久化能力,这是 Hibernate 提供的一个很棒的 程序中对象数据库数据自动同步的方案。

也是一种快速开发方案。

本节课区分了几个常用方法的差异性。但真相似乎就是:大家都和持久化状态有关系。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/50876.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Web前端浅谈ArkTS组件开发

本文由JS老狗原创。 有幸参与本厂APP的鸿蒙化改造,学习了ArkTS以及IDE的相关知识,并有机会在ISSUE上与鸿蒙各路大佬交流,获益颇丰。 本篇文章将从一个Web前端的视角出发,浅谈ArkTS组件开发的基础问题,比如属性传递、插…

hamcrest 断言框架使用示例和优势分析

引言 在软件测试领域,断言是验证代码行为是否符合预期的关键环节。Hamcrest 断言框架,以其独特的匹配器(Matcher)概念和清晰的失败信息,赢得了广泛的赞誉。尽管 Python 标准库中没有内置的 Hamcrest 库,但…

【Linux】-----工具篇(编译器gcc/g++,调试器gdb)

目录 一、gcc/g 简单认识 程序的翻译过程认识gcc 预处理(宏替换) 编译 汇编 链接 宏观认识 如何理解(核心) 什么是链接? 链接的分类 二、gdb 基本的认识 基本操作及指令 安装gdb 启动gdb ​编辑 显示源代码(list) 运行程序…

SQL labs-SQL注入(三,sqlmap使用)

本文仅作为学习参考使用,本文作者对任何使用本文进行渗透攻击破坏不负任何责任。 引言: 盲注简述:是在没有回显得情况下采用的注入方式,分为布尔盲注和时间盲注。 布尔盲注:布尔仅有两种形式,ture&#…

学习笔记:MySQL数据库操作3

1. 创建数据库和表 创建数据库 mydb11_stu 并使用该数据库。创建 student 表,包含字段:学号(主键,唯一),姓名,性别,出生年份,系别,地址。创建 score 表&…

C#、Net6、WebApi报表方案

目录 1 Pdf表单方案 1.1出现如下错误提示: 1.2 字体路径使用 2 Docx报表模板方案 2.1 pdf方案缺陷 2.2 解决方案 3 Spire.Doc报表方案 3.1 Docx方案缺陷 3.2 解决方案 4 插入复选框 5 WebApi文件流下载接口 6 软件获取方式 1 Pdf表单方案 使用【Adobe Acrobat P…

python—pandas基础(2)

文章目录 列操作修改变量列筛选变量列使用.loc[](基于标签)使用.iloc[](基于整数位置)使用.filter()方法 删除变量列添加变量列 变量类型的转换Pandas 支持的数据类型在不同数据类型间转换 建立索引新建数据框时建立索引读入数据时建立索引指…

Vue---vue3+vite项目内使用devtools,快速开发!

背景 我们在前期开发时,一般使用chrome或者edge浏览器,会使用vue-devtools或react-devtools(此插件个人未使用,可百度下是否可内嵌入项目!)来审查vue项目;这个需要安转浏览器插件才可支持&…

使用PyTorch导出JIT模型:C++ API与libtorch实战

PyTorch导出JIT模型并用C API libtorch调用 本文将介绍如何将一个 PyTorch 模型导出为 JIT 模型并用 PyTorch 的 CAPI libtorch运行这个模型。 Step1:导出模型 首先我们进行第一步,用 Python API 来导出模型,由于本文的重点是在后面的部署…

【odoo17】后端py方法触发右上角提示组件

概要 在前面文章中,有介绍过前端触发的通知服务。 【odoo】右上角的提示(通知服务) 此文章则介绍后端触发方法。 内容 直接上代码:但是前提一定是按钮触发!!!!! def bu…

【css】实现扫光特效

对于要重点突出的元素,我们经常可以看到它上面打了一个从左到右的斜向扫光,显得元素亮闪闪的!类似于下图的亮光动效 关键步骤 伪元素设置position :absolute【也可以不用伪元素,直接创建一个absolute元素盖在上面】设置渐变line…

Mike21粒子追踪模型particle tracking如何展示粒子轨迹

前言: 随着模型的推广,模型的很多模块也问的多了起来,PT粒子追踪模块最近群友也在问,结果算了出来,却实现不了展示运动轨迹。今天就写段简单的PT后处理的方法吧。 注意:MIKE21输出模块中不但输出了关于水…

Axure怎么样?全面功能评测与用户体验分析!

软件 Axure 曾经成为产品经理必备的原型设计工具,被认为是专门为产品经理设计的工具。但事实上,软件 Axure 的使用场景并不局限于产品经理构建产品原型。UI/UX 设计师还可以使用 Axure 软件构件应用程序 APP 原型,网站设计师也可以使用 Axure…

如何系统的学习C++和自动驾驶算法

给大家分享一下我的学习C和自动驾驶算法视频,收藏订阅都很高。打开下面的链接,就可以看到所有的合集了,订阅一下,下次就能找到了。 【C面试100问】第七十四问:STL中既然有了vector为什么还需要array STL中既然有了vec…

QSqlQuery增删改查

本文记录使用QSqlQuery实现增删改查的过程。 目录 1. 构建表格数据 声明变量 表格、数据模型、选择模型三板斧设置 列表执行查询 列表的水平表头设置 2. 新增一行 构建一个空行 通过dialog返回的修改行数据,update更新 3. 更新一行 获取到需要更新的行 通…

Spring Bean - xml 配置文件创建对象

类型&#xff1a; 1、值类型 2、null &#xff08;标签&#xff09; 3、特殊符号 &#xff08;< -> < &#xff09; 4、CDATA <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/bea…

信息安全技术解析

在信息爆炸的今天&#xff0c;信息技术安全已成为社会发展的重要基石。随着网络攻击的日益复杂和隐蔽&#xff0c;保障数据安全、提升防御能力成为信息技术安全领域的核心任务。本文将从加密解密技术、安全行为分析技术和网络安全态势感知技术三个方面进行深入探讨&#xff0c;…

WPF启动失败报System.Windows.Automation.Peers.AutomationPeer.Initialize()错误解决

问题描述 win10系统上WPF程序启动后就崩溃&#xff0c;通过查看崩溃日志如下&#xff1a; 应用程序: xxx.exe Framework 版本: v4.0.30319 说明: 由于未经处理的异常&#xff0c;进程终止。 异常信息: System.TypeLoadException 在 System.Windows.Automation.Peers.Automatio…

leetcode-105. 从前序与中序遍历序列构造二叉树

题目描述 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,15,20,7] 输出: [3,9,20,null,nu…

重塑生态体系 深挖应用场景 萤石诠释AI时代智慧生活新图景

7月24日&#xff0c;“智动新生&#xff0c;尽在掌控”2024萤石夏季新品发布会在杭州举办。来自全国各地的萤石合作伙伴、行业从业者及相关媒体&#xff0c;共聚杭州&#xff0c;共同见证拥抱AI的萤石&#xff0c;将如何全新升级&#xff0c;AI加持下的智慧生活又有何不同。 发…