hibernate框架学习之一级缓存
l缓存是存储数据的临时空间,减少从数据库中查询数据的次数
lHibernate中提供有两种缓存机制
•一级缓存(Hibernate自身携带)
•二级缓存(使用外部技术)
lHibernate的一级缓存即Hibernate操作数据时所对应的临时数据存储区域,这个区域是绑定Session对象的,也就是说每开启一个Session对象,就会产生对应的一级缓存空间,当Session对象关闭时,该空间内的数据,也就是其中保存的PO对象,会转化为DO对象。
lHibernate的一级缓存是Session级别的缓存,与Session对象一一对应,不同的Session间无法共享缓存数据。
l验证Hibernate一级缓存的存在性
lget与load方法的区别
•相同:load与get方法查询数据,首先查找一级缓存中是否存在待查找数据,如果存在,直接获取;如果不存在,从数据库中通过SQL语句获取数据库端对应的数据
•不同:load方法查询到的对象,如果只获取数据的OID则不进行任何查询,直接返回OID;如果需要使用OID之外的数据,则按照上述规则查找对应的数据
l通过配置可以关闭延迟加载——lazy属性
Hibernate延迟加载开启与关闭
l在映射文件.hbm.xml文件中,可以配置是否使用延迟加载特性,可以将该属性配置在三个位置
Hibernate使用一级缓存
lHibernate的一级缓存可以理解为数据的中转站
lHibernate进行数据R操作
•如果一级缓存中存在该数据,直接取出使用
•如果一级缓存中不存在,执行SQL语句从数据库中获取
lHibernate进行数据CUD操作
•将待操作的数据及操作模式放入一级缓存
•刷新一级缓存,检测是否需要进行持久化
Hibernate一级缓存刷新方式
lHibernate的一级缓存中保存有本次Session操作过程中的所有数据,这些数据在如下情况提交到数据库进行同步更新,对需要进行更新的数据执行对应的SQL语句
•执行事务提交
•t.commit();
•刷新Session范围的缓存数据
•s.flush();
•关闭Session
•s.close();
Hibernate刷新一级缓存——快照
l当任意数据进入Hibernate一级缓存中时,马上保存该数据的一份克隆(快照),当一级缓存刷新时,对每一个缓存中的对象进行比对,如果快照数据与当前数据相同,无任何操作;如果快照数据与当前数据不同,则将修改后的数据更新到数据库中,执行对应的SQL语句,并更新快照数据
l一级缓冲中保存的对象全是PO,因此PO可以更新数据库对应信息,而TO与DO则不具备这样的能力
l刷新一级缓存
•s.flush();
l清除一级缓存
•s.clear();
l清除一级缓存中指定对象
•s.evict(obj);
l更新一级缓存中指定对象(使用数据库中数据覆盖一级缓存数据及快照数据)
•s.refresh(obj);
Hibernate一级缓存刷新时机
l所谓Hibernate一级缓存刷新时机指一级缓存中存在的修改数据何时会被同步到数据库表中
l常用的刷新时机有四种(FlushModel常量)
•ALWAYS:任意操作导致刷新(效率过低)
•AUTO:根据操作功能区别是否刷新(默认)
•COMMIT:提交事务时刷新
•MANUAL:手动执行刷新时进行刷新(关闭session不会触发)
l设置方式:
•s.setFlushMode(FlushMode.COMMIT);
•设置在Session对象获得后
Hibernate一级缓存常用操作注意事项
lsave()
lupdate()
lmerge()
lsaveOrUpdate()
lget()/load()
ldelete()
lsave操作可以将一个TO转换为PO
l操作步骤:
•将TO装入Session,TO→PO
•使用ID生成器,为PO分配唯一标识OID
•如果手工给出了OID,生成器会根据配置将此OID进行替换
•在执行计划中添加INSERT语句,通过映射文件中的配置,将对象中的属性值添加到INSERT语句中
l注意:
•TO执行了save操作后,TO转换为PO,此时如果修改PO的OID,那么会产生错误,通知用户一个PO的OID发生了变化,这是不被允许的
lupdate操作可以将一个DO转换为PO
l操作步骤:
•为一个TO指定OID,TO→DO
•使用update更新DO,DO→PO
•在执行计划中添加UPDATE语句,通过映射文件中的配置,将对象中的属性值添加到UPDATE语句中
l注意:
•DO转化PO使用update语句完成,如果在转化完成后对PO进行属性更新,只会产生一条update语句,此时PO状态的改变会在缓存进行刷新时才完成最终操作,除非提前刷新缓存
•PO的更新不使用update语句,缓存刷新时自动完成
lUpdate将DO→PO操作会强制完成一次更新操作,无论数据是否发生变化,此时可根据业务需要选择
•如果用户数据没有发生变化,则不执行update语句
•如果用户数据发生了变化,则执行update语句
l完成上述操作的前提是将update操作对应的数据先与数据库中的数据进行比对,也就是update操作前执行查询语句select,可以通过配置完成上述操作
•在class元素中配置select-before-update,该配置值默认false
•
l注意:此设定开启后,整体效率会下降,慎重选择.
lupdate操作将DO转换为PO后,最终将执行对应的UPDATE语句将数据持久化到数据库中,此时如果数据库表中不存在对应OID的数据,程序也将出错
•该错误隶属于基本的SQL操作,SQL语句更新一个不存在的东西将产生0行数据影响的一个操作,而对于Hibernate将此现象归属于执行了一个不可能完成的任务,最终以异常的形式展示给开发者
•例如:A用户读取了一条数据,准备修改该数据,此时B用户将这条数据删除了,A用户在修改该数据时,该数据已经消失,造成上述问题的出现,后期可以通过配置的形式避免该现象的发生,但是效率非常低下。实际业务中,只需要给用户一个合理的提示就行了。
lupdate操作可以将DO转换为PO,但是如果此时Session范围内存在有相同OID的PO对象,此时将报错
l总结:任意时间,同一个Session范围内,不管通过何种方式,如果两个PO具有了同样的OID,那么Hibernate无法区分两个对象,此时将报错
lupdate操作将DO转化为PO时,如果Session范围内存在有相同OID的PO,那么程序将报错。如果要将DO继续转化为PO,可以将两个对象合并成一个,使用merge操作可以完成对象的合并。
lmerge操作是将当前操作的DO属性,合并到OID相同的PO上,最终属性以最后一次修改的为准。如果没有与DO的OID相同的PO,那么merge操作将执行update操作,将DO转化为PO
•存在相同OID的PO,DO合并属性到PO
•不存在相同OID的PO,DO转化为PO
s.merge(um);
lsaveOrUpdate操作是根据对象的状态执行对应操作
•TO执行save操作
•PO无任何操作
•DO执行update操作
l注意:TO的判定标准
•对象的OID为null
•在hbm.xml文件中,为id元素指定unsaved-value属性值,且对象的OID的值与其相同
lget与load方法都可以根据传入的OID值从数据库中获取对应的记录信息,并转换为PO
lget与load读取时加载策略不同(前面已讲解)
lget与load获取数据的区别:
•当DB中不存在get操作获取的OID数据时返回null
•当DB中不存在load操作获取的OID数据时,抛异常
•load方法返回的不是模型对象,而是模型对象的代理对象,因此对于模型类不能使用final修饰,否则将无法创建代理对象
ldelete操作可以从数据库表中删除一条对应的记录
ldelete操作运行原理
•delete操作删除某个对象时,只能对PO进行操作
•如果是DO,首先关联到Session,将DO转化为PO
•TO无法删除
•执行delete操作,在Session范围内对待删除的数据进行删除标记的添加,此时,该对象已经被标记为被删除对象,但还未执行删除语句,数据库中还存在该记录
•刷新缓存时,执行真正的DELETE语句
hibernate框架学习之一级缓存的更多相关文章
- 在Hibernate框架中详谈一级缓存
在学习Hibernate的过程中我们肯定会碰上一个名词---缓存,一直都听说缓存机制是Hibernate中的一个难点,它分为好几种,有一级缓存,二级缓存和查询缓存 今天呢,我就跟大家分享分享我所理解的 ...
- hibernate框架学习之二级缓存(测试用例)
HqlDemoApp.java package cn.itcast.h3.query.hql; import java.io.Serializable; import org.hibernate.Qu ...
- hibernate框架学习之二级缓存
缓存的意义 l应用程序中使用的数据均保存在永久性存储介质之上,当应用程序需要使用数据时,从永久介质上进行获取.缓存是介于应用程序与永久性存储介质之间的一块数据存储区域.利用缓存,应用程序可以将使用的数 ...
- Hibernate框架(四)缓存策略+lazy
Hibernate作为和数据库数据打交道的框架,自然会设计到操作数据的效率问题,而对于一些频繁操作的数据,缓存策略就是提高其性能一种重要手段,而Hibernate框架是支持缓存的,而且支持一级和二级两 ...
- Hibernate框架学习(三)——实体规则、对象状态、一级缓存
一.Hibernate中的实体规则 1.实体类创建的注意事项 1)持久化类提供无参数构造,因为在Hibernate的底层需要使用反射生成类的实例. 2)成员变量私有,提供公有的get和set方法,需提 ...
- hibernate框架学习第三天:对象状态、一级缓存、快照等
对象的状态 瞬时状态: 瞬时对象(TO) 应用程序创建出来的对象,不受H3控制 注意:TO对象不具有OID,一旦为TO赋值OID,那么此时就不是TO 持久化状态:持久化对象(PO) 受H3控制的对象, ...
- hibernate框架学习笔记5:缓存
缓存不止存在与程序中,电脑硬件乃至于生活中都存在缓存 目的:提高效率 比如IO流读写字节,如果没有缓存,读一字节写一字节,效率低下 hibernate中的一级缓存:提高操作数据库的效率 示例: 抽取的 ...
- Hibernate学习之一级缓存
© 版权声明:本文为博主原创文章,转载请注明出处 Hibernate缓存: - 缓存是为了降低应用程序对物理数据源访问的频次,从而提供应用程序的运行性能的一种策略 - Hibernate缓存是提升和优 ...
- hibernate框架学习第六天:QBC、分页查询、投影、数据加载策略、二级缓存
QBC查询 1.简单查询 Criteria c = s.createCriteria(TeacherModel.class); 2.获取查询结果 多条:list 单挑:uniqueResult 3.分 ...
随机推荐
- Hbase记录-Hbase配置项
hbase.tmp.dir:本地文件系统的临时目录,默认是java.io.tmpdir/hbase−java.io.tmpdir/hbase−{user.name}: hbase.rootdir:hb ...
- JMX监控Hadoop的部分常用参数位置
近期版本get无法使用,可能使用了其他参数代替,但源码中已经去掉JMX部分,也没有给出替代接口,应该是不再额外实现了. NameNode DataNode HDFS Yarn HBase MapRed ...
- angular,vue,react的基本语法—双向数据绑定、条件渲染、列表渲染、angular小案例
基本语法: 1.双向数据绑定 vue 指令:v-model="msg" react constructor(){ this.state{ msg:"双向数据绑定" ...
- 理解self与this
刚开始学习Python的类写法的时候觉得很是麻烦,为什么定义时需要而调用时又不需要,为什么不能内部简化从而减少我们敲击键盘的次数?你看完这篇文章后就会明白所有的疑问. self代表类的实例,而非类. ...
- HDU 1097(m次幂的个位数 规律)
题意是求 n^m 结果的最后一位数. 可以用快速幂取模的方法做,当然本题还有更简单的方法: 所有数字( 0 - 9 )的 m 次幂的个位数不会受进位的影响,只收到乘数的影响,所以在结果中一旦出现之前出 ...
- Docker-01 无人值守升级 CentOS 6.x 系统内核到 3.10.x 长期支持版
#!/bin/bash # # 无人值守升级 CentOS .x 系统内核到 3.10.x 长期支持版 # # # .检查操作系统是否为 CentOS .x # cat /etc/centos-rel ...
- 验证调用HttpServletResponse.getWriter().close()方法是否真的会关闭http连接
起因 线上项目突然遭到大量的非法参数攻击,由于历史问题,之前的代码从未对请求参数进行校验. 导致大量请求落到了数据访问层,给应用服务器和数据库都带来了很大压力. 针对这个问题,只能对请求真正到Cont ...
- php 随机生成数字字母组合
直接上代码: function getRandomString($len, $chars=null) { if (is_null($chars)) { $chars = "abcdefghi ...
- (9)EvenOddJump
一.问题描述 一只青蛙从数组(A)的每一个元素向数组尾部跳动.跳动规则如下: 当奇数跳的时候,就是第1.3.5.7....次进行移动时候,移动规则A[i] <= A[j], 并且A[j] = ...
- faster rcnn相关内容
转自: https://zhuanlan.zhihu.com/p/31426458 faster rcnn的基本结构 Faster RCNN其实可以分为4个主要内容: Conv layers.作为一种 ...