Hibernate4之Session一级缓存


Session缓存的作用:
1.减少访问数据库的频率,应用程序从内存中读取持久化对象的速度显然比到数据库查询数据的速度快多了,因此Session的缓存可以提高数据库的访问性能。
2.保证缓存中的对象与数据库中的记录保持同步,当缓存中持久化对象的状态发生了变化,Session并不会立即执行相关的SQL语句,这使得Session能够把几条相关的Sql语句合并为一条sql语句,以便减少访问数据库的次数,从而提高应用程序的性能。


Hibernate中的实体对象的三种状态:
1:瞬时(Transient) - 由new操作符创建,且尚未与Hibernate Session 关联的对象被认定为瞬时的。瞬时对象不会被持久化到数据库中,也不会被赋予持久化标识(identifier)。 如果瞬时对象在程序中没有被引用,它会被垃圾回收器销毁。 使用Hibernate Session可以将其变为持久状态,Hibernate会自动执行必要的SQL语句。

2:持久(Persistent) - 持久的实例在数据库中有对应的记录,并拥有一个持久化标识。 持久的实例可能是刚被保存的,或刚被加载的,无论哪一种,按定义,它存在于相关联的Session作用范围内。 Hibernate会检测到处于持久状态的对象的任何改动,在当前操作单元执行完毕时将对象数据与数据库同步。开发者不需要手动执行UPDATE。将对象从持久状态变成瞬时状态同样也不需要手动执行DELETE语句。

3:脱管(Detached) - 与持久对象关联的Session被关闭后,对象就变为脱管的。 对脱管对象的引用依然有效,对象可继续被修改。脱管对象如果重新关联到某个新的Session上, 会再次转变为持久的,在脱管期间的改动将被持久化到数据库。


通过Session接口来操作Hibernate
新增——save方法、persist方法
1:persist() 使一个临时实例持久化。然而,它不保证立即把标识符值分配给持久性实例,这会发生在flush的时候。persist() 也保证它在事务边界外调用时不会执行 INSERT 语句。这对于长期运行的带有扩展会话/持久化上下文的会话是很有用的。
2:save() 保证返回一个标识符。如果需要运行INSERT来获取标识符(如 "identity" 而非"sequence" 生成器),这个INSERT将立即执行,不管你是否在事务内部还是外部。这对于长期运行的带有扩展会话/持久化上下文的会话来说会出现问题。

当我们调用了session.save(UserModel)后:
1:TO--->PO:Hibernate先在缓存中查找,如果发现在内部缓存中已经存在相同id的PO,就认为这个数据已经保存了,抛出例外。
如果缓存中没有,Hibernate会把传入的这个TO对象放到session控制的实例池去,也就是把一个瞬时对象变成了一个持久化对象。
如果需要Hibernate生成主键值,Hibernate就会去生成id并设置到PO上
2:客户端提交事务或者刷新内存
3:根据model类型和cfg.xml中映射文件的注册来找到相应的hbm.xml文件
4:根据hbm.xml文件和model来动态的拼sql,如下:
insert into 表名(来自hbm.xml) (字段名列表(来自hbm.xml )) values(对应的值的列表(根据hbm.xml从传入的model中获取值))
5:真正用JDBC执行sql,把值添加到数据库
6:返回这个PO的id

修改——load方法、update方法、merge方法和saveOrUpdate方法
1:直接在Session打开的时候load对象,然后修改这个持久对象的属性,在事务提交的时候,Hibernate会判断是否有值改变了,如果没有改变则不会发出SQL,如果改变了会自动flush到数据库中,不过update语句会修改所有字段的值,不管有没有改变(虽然不影响结果,但是不推荐这种方式)。
2:update(会判断修改的对象在session中是否存在,如果不存在,会发出一条修改所有字段的update语句,如果存在,则会比对修改的值,发出修改值不同的update语句)
3:merge(会判断修改的对象在session中是否存在,如果不存在,会去数据库查出数据合并,如果有修改过的数据,发出修改值不同的update语句,如果没有修改就不会发出update语句)
4:自动状态检测:saveOrUpdate方法

update和merge做如下的事情:
1:如果数据库里面存在你要修改的记录,update每次是直接执行修改语句;而merge是先在缓存中查找,缓存中没有相应数据,就到数据库去查询,然后再合并数据,如果数据是一样的,那么merge方法不会去做修改,如果数据有不一样的地方,merge才真正修改数据库。
2:如果数据库中不存在你要修改的记录,update是报错;而merge方法是当作一条新增的值,向数据库中新增一条数据。
3:update后,传入的TO对象就是PO的了,而merge还是TO的。
4:如果你确定当前session没有包含与之具有相同持久化标识的持久实例,使用update()。如果想随时合并改动而不考虑session的状态,使用 merge()。换句话说,在一个新 session中通常第一个调用的是update()方法,以保证重新关联脱管对象的操作首先被执行。
5:请注意:使用update来把一个TO变成PO,那么不管是否修改了对象,都是要执行update sql语句的。

saveOrUpdate做如下的事情:
1:如果对象已经在本session中持久化了,不做任何事
2:如果另一个与本session关联的对象拥有相同的持久化标识,抛出一个异常
3:如果对象没有持久化标识属性,对其调用save()
4:如果对象的持久标识表明其是一个新实例化的对象,对其调用save()。
5:如果对象是附带版本信息的(通过 <version> 或 <timestamp>)并且版本属性的值表明其是一个新实例化的对象,save() 它。
6:否则update()这个对象

merge做如下的事情:
1:如果session中存在相同持久化标识的实例,用用户给出的对象的状态覆盖旧有的持久实例
2:如果session中没有相应的持久实例,则尝试从数据库中加载,或创建新的持久化实例
3:最后返回该持久实例
4:用户给出的这个对象没有被关联到session上,它依旧是脱管的

merge和saveOrUpdate方法区别:
merge方法是把我们提供的对象转变为托管状态的对象;而saveOrUpdate则是把我们提供的对象变成一个持久化对象;说的通俗一点就是:saveOrUpdate后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对象不会纳入session的管理,再次查询该对象还是会从数据库中取。

删除(Id的生成方式为assigned的情况)
当我们调用了session.delete(UserModel)后:
1:根据model的主键在数据库里面查找数据,来保证对象的存在,然后把找到的对象放到内存里面,如果此时在hibernate的实例池中已经存在对应的实体对象(注意:代理对象不算实体对象),就抛出例外。
2:如果此时在hibernate的实例池中不存在对应的实体对象,那么就把对象放到内存里面,但会标识成待删除的对象,就不可以被load等使用了。
3:如果对象还是不存在,那么就直接返回了(注意,这个时候是不抛出例外的)。也就是说,delete之前会执行一个查询语句。
4:客户端提交事务或者刷新内存
5:判断待删除的PO是否存在,存在才需要删除,否则不需要删除
6:如果要删除,才执行以下的步骤。先根据model类型和cfg.xml中映射文件的注册来找到相应的hbm.xml文件
7:根据hbm.xml文件和model来动态的拼sql,如下:
delete from 表名(来自hbm.xml) where 主键=值(来自model)
8:真正用JDBC执行sql,把数据从数据库中删除

删除(Id的生成方式为非assigned的情况)
当我们调用了session.delete(UserModel)后:
1:根据model的主键在hibernate的实例池中查找对应的实体对象(注意:代理对象不算实体对象),找到就使用该对象。
2:如果内存中没有对应的实体对象,就到数据库中查找来保证对象的存在,把找到的对象放到内存里面,而且不会标识成待删除的对象,可以继续被load等使用。代理对象也需要去数据库中查找数据。
3:如果对象还是不存在,那么就抛出例外。也就是说,delete之前可能会执行一个查询语句。
4:客户端提交事务或者刷新内存
5:根据model类型和cfg.xml中映射文件的注册来找到相应的hbm.xml文件
6:根据hbm.xml文件和model来动态的拼sql,如下:
delete from 表名(来自hbm.xml) where 主键=值(来自model)
7:真正用JDBC执行sql,把数据从数据库中删除

值得注意的是,Session只有在清理缓存的时候的才执行delete语句。 commit会调用session的flush方法,刷出session中的数据到数据库,说白了就是同步session中数据到数据库并提交事务。
此外,只有当调用Session的close()方法时,才会从Session的缓存中删除该对象。——————PO(持久化对象)---->DO(托管对象)

查询load和get方法
当我们调用了s.load(UserModel.class, “主键值");后:
1:根据model类型和主键值在一级缓存中查找对象,找到就返回该对象
2:如果没有找到,判断是否lazy=true,如果是,那就生成一个代理对象并返回;否则就先查找二级缓存,二级缓存没有,就查找数据库。如果是返回代理对象的(这时候还不会发出SQL语句),在第一次访问非主键属性的时候(这时候就会发出SQL语句),先查找二级缓存,二级缓存中没有才真正查找数据库,如果还没有找到就抛出异常。
3:如果需要查找数据库的话,会根据model类型和cfg.xml中映射文件的注册来找到相应的hbm.xml文件
4:根据hbm.xml文件和model来动态的拼sql,如下:
select 字段列表(来自hbm.xml) from 表名(来自hbm.xml) where 主键=值
5:真正用JDBC执行sql,把数据从数据库中查询出来到rs里面。如果找不到就报错
6:从结果集---〉Model,然后返回model

注意:load方法开不开事务都可以执行查询语句。

当我们调用了s.get(UserModel.class, “主键值");后:
1:先根据model类型和主键值查找缓存,如果存在具体的实体对象,就返回;如果存在实体的代理对象(比如前面load这条数据,但是还没有使用,那么load生成的是一个只有主键值的代理对象),那么查找数据库,把具体的数据填充到这个代理对象里面,然后返回这个代理对象,当然这个代理对象此时已经完全装载好数据了,跟实体对象没有什么区别了。
2:如果要查找数据库,先根据model类型和cfg.xml中映射文件的注册来找到相应的hbm.xml文件
3:根据hbm.xml文件和model来动态的拼sql,如下:
select 字段列表(来自hbm.xml) from 表名(来自hbm.xml) where 主键=值
4:真正用JDBC执行sql,把数据从数据库中查询出来到rs里面,没有值就返回null
5:从结果集---〉Model,然后返回model

注意:get方法开不开事务都可以执行查询语句。

Session清理缓存的时间点:
清理缓存:是指按照缓存当中的对象的状态的变化来同步更新数据库。
1.当程序调用事物提交的时候,tx.commit()方法被执行时,当前session对象会调用close方法,然后再向数据库提交事物。
2.当程序显示调用session的flush()方法的时候,也会清理缓存。

每间隔一段时间,Session会执行一些必需的SQL语句来把内存中的对象的状态同步到JDBC连接中。这个过程被称为刷出(flush),默认会在下面的时间点执行:
在某些查询执行之前
在调用org.hibernate.Transaction.commit()的时候
在调用Session.flush()的时候
涉及的SQL语句会按照下面的顺序发出执行:
所有对实体进行插入的语句,其顺序按照对象执行Session.save()的时间顺序
所有对实体进行更新的语句
所有进行集合删除的语句
所有对集合元素进行删除,更新或者插入的语句
所有进行集合插入的语句
所有对实体进行删除的语句,其顺序按照对象执行Session.delete()的时间顺序
(有一个例外是,如果对象使用native方式来生成ID(持久化标识)的话,它们一执行save就会被插入。)

除非你明确地发出了flush()指令,关于Session何时会执行这些JDBC调用是完全无法保证的,只能保证它们执行的前后顺序。 当然,Hibernate保证,Query.list(..)绝对不会返回已经失效的数据,也不会返回错误数据。


25003646_rAmx.bmp

转载于:https://my.oschina.net/easyean/blog/535119

【毕业设计】_基于STM32单片机的按摩椅( 原理图+源码) 按摩器系统基于STM32单片机设计,作为核心控制单元。系统配备了OLED显示屏、蓝牙模块、喇叭模块、播报模块和光电感应模块。光电感应器用于检测是否有人接近,同时,系统可以通过蓝牙接收控制指令并执行相应的操作。该系统支持40℃的热敷功能以及气囊按摩功能,具备温度显示功能,并且可以通过按键切换不同的按摩模式。当光电感应器检测到有人时,按摩椅会自动启动。使用DHT11传感器的红色按钮可以调整温度。 阅读详情

相关推荐

西门子【Automation Framework V1.2】AF架构:从软件栈到高效自动化项目的构建蓝图

本文深入解析西门子Automation Framework V1.2 (AF架构) 的核心价值与实施蓝图。该框架通过定义标准化的软件栈(如TIA Portal V19、STEP7、WinCC Unified)和严格的安装配置流程,将自动化项目开发从依赖个人经验的“手工作坊”模式,转变为高效、可复制的工业化模式。遵循此架构,工程师能快速构建稳定可靠的项目基础,规避环境冲突,从而专注于核心工艺与逻辑设计,大幅提升团队协作与项目交付效率。

weixin_29230059的博客 427

Mybatis一级缓存详解

Mybatis一级缓存详解

汤键的博客 1961

gesp c++ 五级知识点

gesp c++ 五级知识点

MMD.然大大 2004

关于session的一级缓存

在session接口的实现中包含一系列的java集合,这些java集合构成了session的缓存,只要session实例没有结束生命周期,且没有清理缓存,则存放在它缓存中的对象也不会结束生命周期。 Session缓存可有效减少应用程序访问数据库的频率。   public void testSession() { News news1 = (News)session.get(News.cla

qq_38935758的博客 437

Fiddler抓包实战:5分钟搞定微信公众号历史消息接口分析(附完整Python代码)

本文详细介绍了如何使用Fiddler抓包工具逆向分析微信公众号历史消息接口,并提供完整的Python代码实现。从环境准备、动态参数捕获到商业级采集系统架构设计,全面解析了突破官方接口限制的技术方案,帮助开发者高效获取公众号文章数据。

tree8的博客 323

千兆以太网PHY设计:PCB原理图完整示例

深入解析千兆以太网PHY电路设计要点,提供完整的PCB原理图设计实例,帮助工程师掌握高速信号布局与电源去耦等关键技术,提升设计稳定性与信号完整性。

weixin_30633869的博客 626

session的缓存(一级缓存)

Session 接口是 Hibernate向应用程序提供的操纵对数据库的最主要的接口,它提供了基本的保存,更新,删除和加载Java 对象的方法。   在 Session 接口的实现中包含一系列的 Java 集合,这些 Java 集合构成了 Session 缓存。只要 Session 实例没有结束生命周期,存放在它缓存中的对象也不会结束生命周期(因为还有这些集合引用对象)。   当sessi

颜枫 1745

基于STC8G1K08A单片机的PCA捕获外部信号(100~1000HZ)程序实现

基于STC8G1K08A单片机的PCA捕获外部信号(100~1000HZ)程序实现

weixin_74013772的博客 252

HibernateDay02(持久化类 悲乐观锁 事务 session一级缓存 Criteria接口查询)

持久化类 就是一个Java类(编写的JavaBean),这个Java类与表建立了关系就可以成为持久化类 持久化类 = JavaBean + xxx.hbm.xml 持久化类的编写规则 1、提供一个无参数 public访问控制符的构造器 底层需要进行反射 2、提供一个标识属性,映射数据表主键字段 唯一标识OID,数据库中通过主键。Java对...

civilizationV的博客 254

【ARFoundation自学04】AR Tracked Image 图像追踪识别与对应类的调用

1.添加组件 2.创建图像识别库 3.创建识别后追踪的物体(UI、模型等)

leoysq的博客 2559

RK平台以太网设置中添加代理设置

以太网中配置Configuration的时候可以IpConfiguration的初始化函数来设置代理类型和代理参数。通过添加一个KEY_ETH_PROXY的选项来设置代理的配置,然后再设置以太网静态或者动态的类型时候下发给系统进行设置。

Android系统开发笔记 655

hibernate4的session一级缓存

注:       1. 是session级别的,只缓存对象      2.好像不可以关闭     3. 对于query中的list()和iterate()方法,有N+1问题,即list()是直接去数据库里面查,而iterate()是想去数据库里查询id,然后根据id去缓存里面查数据,没有再去数据库里查 session = HibernateUtils.getSession();

嵇康的专栏 739

UNet + Shuffle Attention:一种轻量高效的医学图像分割注意力机制

本文提出了一种轻量高效的医学图像分割方法,将Shuffle Attention模块嵌入UNet的上采样路径中。Shuffle Attention通过通道分组注意力机制增强关键特征,同时保持计算轻量化。该方法在上采样后应用注意力模块,有效融合高层语义与低层细节,计算开销小且易于部署。实验表明,该模型在保持UNet原有优势的基础上,通过注意力机制提升了特征聚焦能力,适用于多种图像分割任务。未来可进一步结合空间注意力或Transformer模块以增强模型性能。

Henry的博客 238

4-7. Hibernate_Session 概述&缓存(Hibernate 一级缓存)&Session 核心方法

核心方法:package com.hgh.hibernate.helloworld;import static org.junit.Assert.*;import java.sql.Connection; import java.sql.SQLException; import java.util.Date;import org.hibernate.Session; import org.hiber

y41992910的博客 291

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Hibernate 二级缓存举例(4.2 Final版)

Hibernate 4.2里面的缓存 1、 hibernate 里面的缓存分成一级缓存与二级缓存与查询缓存 一级缓存:Session级别的缓存二级缓存:SessionFactory级别的缓存查询缓存 2、 一级缓存 @Test public void testCache() { Session s = sf.getCurrentSession(); s.beginTrans

Q码记 485

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Hibernate的学习之路十一(Session的一级缓存和证明存在)

前言 这篇文章主要是说明了,session这个一级缓存,给了个概念,以及通过代码证明一级缓存的存在。session是一级缓存生命周期短暂,通过sessionFactory来强化一级缓存。 分析 Session对象的一级缓存(重点) 1. 什么是缓存? * 其实就是一块内存空间,将数据源(数据库或者文件)中的数据存放到缓存中.再次获取的时候 ,直接从缓存中获取.可以提

玩垃圾的人 349

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Hibernate框架(2)操作对象和一级缓存

Hibernate框架(2)操作对象和一级缓存主要内容1. Hibernate持久化对象的状态 2. Hibernate的一级缓存 3. Hibernate操作持久化对象的方法 4. Hibernate的基本查询 Hibernate的持久化类什么是持久化类1. 持久化类:就是一个Java类(咱们编写的JavaBean),这个Java类与表建立了映射关系就可以成为是持久化类。 * 持久化类 =

阳光丶不锈 382

Hibernate——(5)持久化对象和一级缓存机制

一、对象的三种状态 1、暂时态:当对象刚创建,和Session没有发生任何关系时,当程序运行完就即刻消失,被称为暂时态。 2、持久态:当执行如下代码时,对象变为持久态 Emp e = new Emp(); session.save(); 持久态的对象和Session发生了关系,如执行了save,get,query等方法 Session中会缓存该对象(Session的缓存叫一级缓存)

程序员的那些事 683

Hibernate的一级缓存

Hibernate的一级缓存Hibernate的一级缓存就是指Session缓存。通过查看Session接口的实现类——SessionImpl.java的源码可发现有如下两个类: actionQueue它是一个行动队列,它主要记录crud操作的相关信息。 persistenceContext它是持久化上下文,它其实才是真正的缓存。 在Session中定义了一系列的集合来存储数据,它们构成了Sessi

李阿昀的博客 8281

Hibernate总结以及在面试中的一些问题.

什么要使用Hibernate开发你的项目呢?Hibernate的开发流程是怎么样的为什么要使用 ①.对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。  ②.Hibernate 是一个基于JDBC的主流持久化框架,是一个优秀的ORM 实现。他很大程度的简化DAO层的编码工作  ③.hibernate 的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种...

ghostxbh‘s blog 372

Hibernate的一级缓存与二级缓存的优缺点及缓存的生命周期

如果项目既使用了 Hibernate 又需要 Redis,可以考虑将 **Redis** 作为二级缓存的存储后端。在这种情况下,Hibernate 二级缓存的管理和缓存数据的存取将交由 Redis 来完成,既享受了 Hibernate 集成的便利,又利用了 Redis 在分布式、高并发场景中的优势。

qq1004722157的博客 1205

浅谈Hibernate缓存机制:一级缓存、二级缓存

浅谈Hibernate缓存机制:一级缓存、二级缓存

VipMao的博客 7227

hibernate缓存:一级缓存和二级缓存

hibernate缓存:一级缓存和二级缓存 1.什么是缓存?  缓存是介于物理数据源与应用程序之间,是对数据库中的数据复制一份临时放在内存中的容器,其作用是为了减少应用程序对物理数据源访问的次数,从而提高了应用程序的运行性能。Hibernate在进行读取数据的时候,根据缓存机制在相应的缓存中查询,如果在缓存中找到了需要的数据(我们把这称做“缓存命中"),则就直接把命中的数据作为结果加以...

莫等闲的博客 927

HIbernate的一级缓存和快照

什么是Hibernate的一级缓存        Hibernate的一级缓存就是指Session缓存,Session缓存是一块内存空间,用来存放相互管理的java对象,在使用Hibernate查询对象的时候,首先使用对象属性的OID值在Hibernate的一级缓存种进行查找,如果找到匹配OID值的对象,就直接将该对象从一级缓存...

吴声子夜歌的博客 1088

Hibernate之一级缓存和二级缓存

Hibernate之一级缓存和二级缓存 1:Hibernate的一级缓存:   1.1:使用一级缓存的目的是为了减少对数据库的访问次数,从而提升hibernate的执行效率;(当执行一次查询操作的时候,执行第二次查询操作,先检查缓存中是否有数据,如果有数据就不查询数据库,直接从缓存中获取数据);   1.2:Hibernate中的一级缓存,也叫做session的缓存,它可以在session...

莫等闲的博客 246

Hibernate学习笔记:理解一级缓存和session清理

[本文大多数内容都来自互联网]Session执行一些sql语句把内存中的对象的状态同步到数据库,这个过程被称为session清理.在默认情况下,Session会在下面的时间点清理缓存。1 当应用程序调用net.sf.hibernate.Transacation的commit()方法的时候,commit()方法先清理缓存,然后再向数据库提交事务。 2 当应用程序调用Session的find()或

sunxing007的专栏 3958
上一篇: Hibernate4之一对多双向关联
下一篇: Spring3核心技术之AOP配置
chifancui9836
博客等级 码龄11年 0粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值