您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > Java_Hibernate缓存深入详解
Hibernate缓存深入详解大纲Hibernate缓存概述1Hibernate一级缓存(Session缓存)23Hibernate二级缓存4二级缓存的高级应用(分布式缓存)5查询缓存1-1:Hibernate缓存概述Hibernate缓存机制对Hibernate的性能发挥一直处于一个极其重要的作用,它是持久层性能提升的关键。hibernate缓存在应用系统中的位置Hibernate缓存介于Hibernate应用和数据库之间,缓存中存放了数据库数据的拷贝。其作用是减少访问数据库的频率,从而提高应用的运行性能。Hibernate在进行读取数据的时候,根据缓存机制在相应的缓存中查询,如果在缓存中找到了需要的数据(我们把这称做“缓存命中”),则就直接把命中的数据作为结果加以利用,避免的了建立数据库查询的性能损耗。应用程序Hibernate缓存永久性数据存储源(数据库)频繁写偶尔写频繁读偶尔读1-2:Hibernate缓存分类Hibernate提供了两级缓存:一级缓存:Session级别的缓存二级缓存:SessionFactory级别的全局缓存Hibernate的这两级缓存都位于持久化层,存放的都是数据库数据的拷贝。那么它们之间的区别是什么呢?为了理解二者的区别,需要深入理解持久化层的缓存的一个特性:缓存的范围。1-3:缓存的范围(1)缓存的范围决定了缓存的生命周期以及可以被谁访问。缓存的范围分为三类。事务范围缓存只能被当前事务访问。缓存的生命周期依赖于事务的生命周期,当事务结束时,缓存也就结束生命周期。缓存的介质是内存。事务可以是数据库事务或者应用事务,每个事务都有独自的缓存,缓存内的数据通常采用相互关联的的对象形式。一级缓存就属于事务范围。事务1范围的缓存Dept对象deptCode=001Dept对象deptCode=002内存User对象UserCode=001001事务2范围的缓存Dept对象deptCode=001Dept对象deptCode=002User对象UserCode=0010011-3:缓存的范围(2)进程范围缓存被进程范围内的所有事务共享。这些事务有可能并发访问缓存,因此必须对缓存采取必要的事务隔离机制。缓存的生命周期依赖于进程的生命周期,进程结束时,缓存也就结束了生命周期。它的物理介质可以是内存或硬盘。进程范围的缓存Dept对象deptCode=001Dept对象deptCode=002User对象UserCode=001001内存/硬盘事务1范围的缓存事务2范围的缓存1-3:缓存的范围(3)集群范围在集群环境中,缓存被一个机器或者多个机器的进程共享。缓存中的数据被复制到集群环境中的每个进程节点,进程间通过远程通信来保证缓存中的数据的一致性,缓存中的数据通常采用对象的松散数据形式。持久化层的第二级缓存就存在于进程范围或集群范围。大纲Hibernate缓存简介1Hibernate一级缓存(Session缓存)23Hibernate二级缓存查询缓存4二级缓存的高级应用(分布式缓存)52-1:理解一级缓存(1)Session具有一个缓存,是一块内存空间,在这个内存空间存放了相互关联的java对象,这种位于Session缓存内的对象也被称为持久化对象,Session负责根据持久化对象的状态变化来同步更新数据库。Session的缓存是内置的,不能被卸除的,也被称为Hibernate的第一级缓存。在正常的情况下一级缓存是由Hibernate自动维护的,无需人工干预。Session实例内存Session缓存Dept对象User对象引用变量ssession缓存中对象的生命周期依赖session实例2-1:理解一级缓存(2)(1)当应用程序调用Session接口的save()、update()、saveOrUpdate()时,如果Session缓存中还不存在相应的对象,Hibernate就会把该对象加入到第一级缓存中。(2)当调用Session接口的load()、get()以及Query查询接口的list()、iterator()方法时,如果Session缓存中存在相应的对象,就不需要到数据库中检索。(3)当调用Session的close()时,Session缓存就被清空。实体对象Session缓存内存数据库session.load()session.save()实体对象2-2:Session接口的用法(1)Session接口是Hibernate向应用程序提供的操纵数据库的最主要的接口,它提供了基本的保存、更新、删除和加载等方法。Java对象在Hibernate持久化层的状态:临时状态:刚用new语句创建,还没有被持久化,并且不处于session缓存中(处于临时状态的对象成为临时对象)持久化状态:已经被持久化,并且加入到session缓存中。处于持久化状态的对象称为持久化对象删除状态:不再处于session缓存中,并且session已经计划将其从数据库中删除游离状态:已经被持久化,但不再处于session缓存中。处于游离状态的对象称为游离对象2-2:Session接口的用法(2)save()和persist()save()方法把一个临时对象加入到Session缓存中,并持久化该临时对象,计划执行一个insert语句。persist()和save()方法类似,也能把把一个临时对象转变为持久化对象。区别:(1)persist()是在Hibernate3版本中才出现。在使用代理主键的情况下persist()方法不保证立即为持久化对象的ID赋值,而是有可能在Session清理缓存时才为ID赋值。(2)如果在事务边界以外调用persist()方法,那么该方法不会计划执行insert语句,这可以提高负责长时间运行事务的程序的健壮性。而save()方法,不管是在事务边界以外或以内调用它,都会计划执行insert语句。2-2:Session接口的用法(3)get()和load()试图从数据库加载一个实体对象时,Session先判断对象是否存在,如果存在就不到数据库中检索。返回的对象都位于Session缓存中,接下来修改了持久化对象的属性后,当Session清理缓存时,会根据持久化对象的属性变化来同步更新数据库。区别:(1)当数据库中不存在与OID对应的记录时,load()方法抛出ObjectNotFoundException异常,而get()方法返回null.(2)两者采用不同的检索策略。默认情况下,load()方法采用延迟检索策略(Hibernate不会执行select语句,仅返回实体类的代理类实例,占用内存很少);而get()采用立即检索策略(Hibernate会立即执行select语句)。使用场合:(1)如果加载一个对象的目的是为了访问它的各个属性,可以用get();(2)如果加载一个对象的目的是为了删除它,或者建立与别的对象的关联关系,可以用load();2-2:Session接口的用法(3)update()和merge()update()方法把游离对象加入当前Session缓存中,计划执行update语句。当update()方法关联一个游离对象时,如果session缓存中已经有一个同类型且ID相同的持久化对象,那么update()方法会抛出NonUniqueException异常.当update()方法关联一个持久化对象时,该方法不起作用。merge()方法能够把游离对象的属性复制到一个持久化对象中。2-2:Session接口的用法(4)merge()方法的处理流程dept1对象的状态ID=001Session缓存中是否存在ID为001的Dept持久化对象数据库中是否存在ID为001的Dept持久化对象从数据库中加载ID为001的Dept持久化对象把dept1游离对象的属性拷贝到Dept持久化对象dept2中,计划执行一条update语句创建一个新的Dept对象,把dept1对象的属性拷贝到新建的Dept对象中,持久化这个Dept对象,计划执行一条insert语句返回Dept对象的引用游离对象临时对象不存在存在不存在存在(dept2)2-2:Session接口的用法(4)saveOrUpdate()同时包含了save()和update()方法的功能。如果传入的是临时对象,就调用save()方法;如果传入的是游离对象,就调用update()方法如果传入的是持久化对象,就直接返回。delete():计划执行一个delete语句,把对象从Session缓存中删除。close():清空session缓存。2-3:Session清理缓存清理缓存是指Session按照缓存中对象的属性变化来同步更新数据库。Session在清理缓存的时候会自动进行脏检查(dirty-check),如果发现Session缓存中的对象与数据库中相应的记录不一致,就会同步数据库。Session是如何进行脏检查的呢?当一个对象被加入到Session缓存时,Session会为该对象的值类型的属性复制一份快照。当Session清理缓存的时候,会进行脏检查,即比较对象的当前属性与它的快照,来判断对象的属性是否发生变化,如果发生变化,就称这个对象是“脏对象”,Session会根据脏对象的最新属性来执行相关的SQL语句,从而同步更新数据库。2-4:Session脏检查及同步数据库的过程SessionDept对象(deptCode=001,deptName=人事部)Session缓存1.session.get()Dept对象(deptCode=001,deptName=人力资源部)Session缓存2.dept.setDeptName(“人力资源部”)Dept对象(deptCode=001,deptName=人力资源部)Session缓存3.Session进行脏检查dept_codedept_name001人力资源部4.执行update语句,同步更新数据库Dept对象的快照(deptCode=001,deptName=人事部)Dept对象的快照(deptCode=001,deptName=人事部)清理缓存Dept对象的快照(deptCode=001,deptName=人事部)两者不匹配2-5:Session何时清理缓存(1)session缓存中对象的属性每次发生变化,Session不会立即清理缓存及执行相关的update语句,而是在特定的时间点才清理缓存,这使得Session能够把几条相关的sql语句合并为一条sql语句,以便减少访问数据库的次数。以下代码对dept对象的deptName属性修改了两次:Transactiontx=session.biginTransaction();Deptdept=(Dept)session.get(Dept.class,”001”);dept.setDeptName(“人事部”);dept.setDeptName(“人力资源部”);tx.commit();当Session清理缓存时,只会执行一条update语句Dept对象Session缓存内存数据库session.load()同步更新数据库2-5:Session何时清理缓存(2)session会在下面的时间点清理缓存:(1)当应用程序调用org.hibernate.Transaction的commit()方法的时候commit()方法先清理缓存,然后再向数据库提交事务。(2)当应用程序执行一些查询操作时,如果缓存中持久化对象的属性已经发生变化,就会先清理缓存,使得Session缓存与数据库进行了同步,从而保证查询结果返回的是正确的数据。(3)当应用程序显式调用Session的flush()方法的时候2-6:Sesion缓存的管理第一级缓存在正常的情况下是由Hibernate自动维护的。在特殊的情况下需要我们进行手动维护,Hibernate就提供了两个管理Session缓存的方法:(1)Session.evict(Objecto)将某个特定的对象从缓存
本文标题:Java_Hibernate缓存深入详解
链接地址:https://www.777doc.com/doc-2880494 .html