快速业务通道

Hibernate获取数据方式与缓存使用 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-16

Hibernate获取数据方式与缓存使用

时间:2011-07-25 BlueDavy

Hibernate获取数据的方式有不同的几种,其与缓存结合使用的效果也不尽相同,而Hibernate中具体 怎么使用缓存其实是我们很关心的一个问题,直接涉及到性能方面。

缓存在Hibernate中主要有三个方面:一级缓存、二级缓存和查询缓存;一级缓存在Hibernate中对应 的即为session范围的缓存,也就是当session关闭时缓存即被清除,一级缓存在Hibernate中是不可配置 的部分;二级缓存在Hibernate中对应的即为SessionFactory范围的缓存,通常来讲SessionFactory的生 命周期和应用的生命周期相同,所以可以看成是进程缓存或集群缓存,二级缓存在Hibernate中是可以配 置的,可以通过class-cache配置类粒度级别的缓存(class-cache在class中数据发生任何变化的情况下自 动更新),同时也可通过collection-cache配置集合粒度级别的缓存(collection-cache仅在collection中 增加了元素或者删除了元素的情况下才自动更新,也就是当collection中元素发生值的变化的情况下它是 不会自动更新的),缓存自然会带来并发的访问问题,这个时候相应的就要根据应用来设置缓存所采用的 事务隔离级别,和数据库的事务隔离级别概念基本一样,没什么多介绍的,^_^;查询缓存在Hibernate同 样是可配置的,默认是关闭的,可以通过设置cache.use_query_cache为true来打开查询缓存。根据缓存 的通常实现策略,我们可以来理解Hibernate的这三种缓存,缓存的实现通过是通过key/value的Map方式 来实现,在Hibernate的一级、二级和查询缓存也同样如此,一级、二级缓存使用的key均为po的主键ID, value即为po实例对象,查询缓存使用的则为查询的条件、查询的参数、查询的页数,value有两种情况, 如果采用的是select po.property这样的方式那么value为整个结果集,如采用的是from这样的方式那么 value为获取的结果集中各po对象的主键ID,这样的作用很明显,节省内存,^_^

简单介绍完Hibernate的缓存后,再结合Hibernate的获取数据方式来说明缓存的具体使用方式,在 Hibernate中获取数据常用的方式主要有四种:Session.load、Session.get、Query.list、 Query.iterator。

1、Session.load

在执行session.load时,Hibernate首先从当前session的一级缓存中获取id对应的值,在获取不到的 情况下,将根据该对象是否配置了二级缓存来做相应的处理,如配置了二级缓存,则从二级缓存中获取id 对应的值,如仍然获取不到则还需要根据是否配置了延迟加载来决定如何执行,如未配置延迟加载则从数 据库中直接获取,在从数据库获取到数据的情况下,Hibernate会相应的填充一级缓存和二级缓存,如配 置了延迟加载则直接返回一个代理类,只有在触发代理类的调用时才进行数据库查询的操作。

在这样的情况下我们就可以看到,在session一直打开的情况下,要注意在适当的时候对一级缓存进行 刷新操作,通常是在该对象具有单向关联维护的时候,在Hibernate中可以使用象session.clear、 session.evict的方式来强制刷新一级缓存。

二级缓存则在数据发生任何变化(新增、更新、删除)的情况下都会自动的被更新。

2、Session.get

在执行Session.get时,和Session.load不同的就是在当从缓存中获取不到时,直接从数据库中获取id 对应的值。

3、Query.list

在执行Query.list时,Hibernate的做法是首先检查是否配置了查询缓存,如配置了则从查询缓存中查 找key为查询语句+查询参数+分页条件的值,如获取不到则从数据库中进行获取,从数据库获取到后 Hibernate将会相应的填充一级、二级和查询缓存,如获取到的为直接的结果集,则直接返回,如获取到 的为一堆id的值,则再根据id获取相应的值(Session.load),最后形成结果集返回,可以看到,在这样的 情况下,list也是有可能造成N次的查询的。

查询缓存在数据发生任何变化的情况下都会被自动的清空。

4、Query.iterator

在执行Query.iterator时,和Query.list的不同的在于从数据库获取的处理上,Query.iterator向数 据库发起的是select id from这样的语句,也就是它是先获取符合查询条件的id,之后在进行 iterator.next调用时才再次发起session.load的调用获取实际的数据。

可见,在拥有二级缓存并且查询参数多变的情况下,Query.iterator会比Query.list更为高效。

这四种获取数据的方式都各有适用的场合,要根据实际情况做相应的决定,^_^,最好的方式无疑就是 打开show_sql选项看看执行的情况来做分析,系统结构上只用保证这种调整是容易实现的就好了,在 cache这个方面的调整自然是非常的容易,只需要调整配置文件里的设置,而查询的方式则可对外部进行 屏蔽,这样要根据实际情况调整也非常容易。

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号