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

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这个方面的调整自然是非常的容易,只需要调整配置文件里的设置,而查询的方式则可对外部进行 屏蔽,这样要根据实际情况调整也非常容易。

时间: 2025-01-21 02:03:10

Hibernate获取数据方式与缓存使用的相关文章

Android远程获取图片并本地缓存_Android

对于客户端--服务器端应用,从远程获取图片算是经常要用的一个功能,而图片资源往往会消耗比较大的流量,对应用来说,如果处理不好这个问题,那会让用户很崩溃,不知不觉手机流量就用完了,等用户发现是你的应用消耗掉了他手机流量的话,那么可想而知你的应用将面临什么样的命运. 另外一个问题就是加载速度,如果应用中图片加载速度很慢的话,那么用户同样会等到崩溃. 那么如何处理好图片资源的获取和管理呢? *异步下载 *本地缓存 1.异步下载: 大家都知道,在android应用中UI线程5秒没响应的话就会抛出无响应异

Android远程获取图片并本地缓存

对于客户端--服务器端应用,从远程获取图片算是经常要用的一个功能,而图片资源往往会消耗比较大的流量,对应用来说,如果处理不好这个问题,那会让用户很崩溃,不知不觉手机流量就用完了,等用户发现是你的应用消耗掉了他手机流量的话,那么可想而知你的应用将面临什么样的命运. 另外一个问题就是加载速度,如果应用中图片加载速度很慢的话,那么用户同样会等到崩溃. 那么如何处理好图片资源的获取和管理呢? *异步下载 *本地缓存 1.异步下载: 大家都知道,在android应用中UI线程5秒没响应的话就会抛出无响应异

httpclient连续访问网页获取数据,是否会遇到缓存

问题描述 我用httpclient的get方法持续访问一个页面,基本上一秒发一次get请求,获取页面上面的文本,这个文本信息是会根据服务器端数据更新的.打个比方,这个信息一般为"False",一天中会有30秒变为"TRUE",我需要捕获这个"TRUE"信息.但是我发现即使服务器端更新了,我的程序获取的依然是"FALSE",并没有获取到更新的信息.我用wireshark监测,我的确是每秒发出一个get请求.那为什么会没拿到那个更

node.js下IE中获取数据的缓存

IE下默认会开启缓存策略,不管是页面还是通过ajax请求的数据都会议一个url,url是uri(统一资源定位符)的实例,url就是资源的标识符. 写一个demo进行验证,测试环境:IE8,node.js 0.12.7,页面模板为jade.  页面代码:testCache.jade 页面上放一个按钮,点下后从后台获取一个自增的数值显示在按钮上. doctype htmlhtml    head        meta(charset='utf-8')        title= title    

activemq-使用消息队列的方式从一个数据平台获取数据

问题描述 使用消息队列的方式从一个数据平台获取数据 是如何保证数据的不重复?也就是说每次取数据都要按照时间字段做限制?还是说不需要关心这个,他给什么就收什么?是多线程的吗,实时保持通信?望好心人做做解答.多谢 解决方案 看什么数据来源,它本身是否支持对消息的唯一编码.如果没有唯一的编码,那么只能以时间戳来作为唯一的依据.消息队列一般都是支持多线程并发的,但是你的程序仍然需要做相应的处理. 解决方案二: 虽然你没有提供多少细节,但是一些常识性的东西可以回答你,根据著名的cap原则,在分布式系统上,

java-SSH JSP页面显示不出Action值来,Hibernate获取值正常,可以插入数据,求大神速回!

问题描述 SSH JSP页面显示不出Action值来,Hibernate获取值正常,可以插入数据,求大神速回! import java.sql.Date;import java.util.List; /** 商品业务*/public class BlurbServiceImpl{BlurbDAO blurbDAO = (BlurbDAO)AppContext.getBean(""blurbDAO""); /* 修改/public void updateBlurb(S

php curl file_get_contents post方式获取数据

curl post,file_get_contents post,curl file_get_contents post请求数据 在PHP中cURL.file_get_contents函数均可以获取远程链接的数据,但是file_get_contents的可控制性不太好,对于各种复杂情况的数据采集情景,file_get_contents显得有点无能为力,cURL在数据采集情景复杂的环境下略显优势.cURL函数的curl_setopt里面还有很多参数,读者可以抽空整体看一遍,虽然平时未必用得上,但是

Ajax的jsonp方式跨域获取数据的简单实例_AJAX相关

jsonp的调用,今天碰到了,正好整理了一下. <!DOCTYPE html> <html> <head> <script src="http://libs.baidu.com/jquery/1.9.1/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function(){ $("#b

以用户名注册为例分析三种Action获取数据的方式_java

1.注入属性 直接注入属性: public String userName; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } @Override public String execute() throws Exception { // TODO Auto-generated method stub Use