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语句

原文地址:https://www.cnblogs.com/xyhero/p/9351699.html

时间: 2024-08-02 02:48:31

hibernate框架学习之一级缓存的相关文章

在Hibernate框架中详谈一级缓存

在学习Hibernate的过程中我们肯定会碰上一个名词---缓存,一直都听说缓存机制是Hibernate中的一个难点,它分为好几种,有一级缓存,二级缓存和查询缓存 今天呢,我就跟大家分享分享我所理解的一级缓存 要想完美的体现出缓存机制的话,我想通过查询语句生成的sql应该就能够很清楚的看到 那些Hibernate的配置信息我就不展示了,直接看关键代码 场景:我要查询同一个对象,查询两次,观察在不同的情况下,sql语句的生成情况 我事先准备了一个HibernateUtil工具类,具体如下 pack

一级缓存 ---- Hibernate框架学习

叙:hibernate中有一个特色,即,hibernate的持久态能自动更新数据库,不需要手动设置更新操作代码,而持久态的这一特色所依据的便是hibernate的一级缓存技术.那么之前学过了hibernate的三态,现在学习一下一级缓存: hibernate的一级缓存 首先,要明白什么是缓存: 什么是缓存? 缓存:一种优化方式,将数据存储在本地,当使用到保存的数据时不必再向服务器或者终端进行请求数据的操作,直接读取本地数据即可. 然后现在了解一下hibernate的缓存: hibernate缓存

Hibernate学习之一级缓存

? 版权声明:本文为博主原创文章,转载请注明出处 Hibernate缓存: - 缓存是为了降低应用程序对物理数据源访问的频次,从而提供应用程序的运行性能的一种策略 - Hibernate缓存是提升和优化Hibernate执行效率的重要手段 工作原理: 1. 应用程序读取缓存数据 2. 缓存命中则直接返回数据 3. 缓存未命中则去数据库中查询数据,然后将数据放入缓存中并返回数据 一级缓存: 1. Hibernate一级缓存又称为"Session缓存"."会话级缓存"

hibernate框架学习笔记5:缓存

缓存不止存在与程序中,电脑硬件乃至于生活中都存在缓存 目的:提高效率 比如IO流读写字节,如果没有缓存,读一字节写一字节,效率低下 hibernate中的一级缓存:提高操作数据库的效率 示例: 抽取的工具类 package utils; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUt

j2ee开发之hibernate框架学习笔记

hibernate框架技术重点学习笔记 1.针对不同的数据库,有不同的数据库实现类,使其符号对应的数据库? mysqlDaoImpl oracleDaoImpl ... ... 2.对象和表记录的转换存在着转换问题->orm,对象和关系的一种映射 3.框架:解决一种问题的方案集合! 4..配置文件 Xxx.cfg.xml  主配置文件 xxx.hbm.xml映射文件: 映射基础 普通属性 主键 集合属性 关联关系:一对多  多对一 多对多  一对一 继承结构 5.其他特性:数据库连接池  懒加载

持久化类(状态介绍)---- Hibernate框架学习

叙:之前介绍了持久化.持久化类的相关信息,关于持久化类只讲了相关编写规则等(文章地址:https://www.cnblogs.com/Email-qtl777777/p/9650239.html),关于其内部的更多的划分并没进行细讲,本章电虫就持久化类的三个状态以及三种状态的区分以及三种状态的区分进行学习.记录: 持久化类的三种状态 Hibernate是持久层框架,通过持久化的类完成ORM(Java对象和数据库表的映射关系)操作:hibernate为更好地管理持久化类的状态,特此将持久化类分成三

Mybatis学习笔记-一级缓存

参考:http://blog.csdn.net/luanlouis/article/details/41280959 Mybatis是一个小巧.强大的ORM框架,主要功能与Hibernate类似,但比Hibernate更加灵活,简单. 我们都知道,数据库操作是一个应用中比较耗费资源的一点,Mybatis作为最好用的orm框架,当然在这方面也做了优化,同样,与hibernate类似,mybatis也提供了一级缓存和二级缓存来提高数据访问层(Dao)的性能. 下面详细介绍一个mybatis的一级缓存

二、框架学习 (一)Hibernate框架学习 (2)Hibernate概念和api使用

目录 1 实体类编写规则 2 hibernate主键生成策略 3 实体类操作 (1)crud操作 (2)实体类对象状态 4 hibernate的一级缓存 5 hibernate的事务操作 (1)事务代码规则写法 6 hibernate其他的api(查询) 正文 实体类编写规则 1 实体类里面属性是私有的 2 私有属性使用公开的set和get方法操作. 3 要求实体类有属性作为唯一值(一般使用id值) 4 实体类属性建议不使用基本数据类型,使用基本数据类型对应的包装类 (1)八个基本数据类型对应的

[ SSH框架 ] Hibernate框架学习之四(JPA)

一.JPA概述以及它和Hibernate之间的关系 1.1.Hibernate 概述 JPA Java Persistence API,是EJB3规范中负责对象持久化的应用程序编程接口(ORM接口),它定义一系列的注释.这些注释大体可分为:类级别注释.方法级别注释.字段级别注释.给实体类添加适当的注释可以在程序运行时告诉Hibernate如何将一个实体类保存到数据库中以及如何将数据以对象的形式从数据库中读取出来. 目前有两种注释方案可以确定对象与表格之间的对应关系:一种是注释实体类的属性字段(字