网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.迈博科技推出Ubox广域协同工作系.
.用JAVA编写自己的机器人,然后一.
.anchor 方法.
.基于Java 2平台的引用类使用指南.
.SpringFramework 入门实用攻略.
.用Java编写扫雷游戏--算法思考.
.VisualCafé pro1.0--轻松Java编.
.用JDom整合Java和XML(1).
.Java在Client/Server网络中的应用.
.Eclipse In Action1.3.
.Java助力火星探测 其认证深受重视.
.六个 for 循环的Java小程序源码展.
.通过JDMK 进行遗留系统管理.
.Java类 精彩问答.
.OReilly新书推荐:《游戏开发物理.
.Resin服务器平台介绍.
.substring 方法.
.Java学习从入门到精通.书籍篇.
..net开发趣题两则-联想优秀程序员.
.在S1AS7中配置MySQL(支持CMP).

Hibernate二级缓存攻略

发表日期:2008-1-5



  很多人对二级缓存都不太了解,或者是有错误的熟悉,我一直想写一篇文章介绍一下hibernate的二级缓存的,今天终于忍不住了。

  我的经验主要来自hibernate2.1版本,基本原理和3.0、3.1是一样的,请原谅我的顽固不化。

  hibernate的session提供了一级缓存,每个session,对同一个id进行两次load,不会发送两条sql给数据库,但是session关闭的时候,一级缓存就失效了。

  二级缓存是SessionFactory级别的全局缓存,它底下可以使用不同的缓存类库,比如ehcache、oscache等,需要设置hibernate.cache.provider_class,我们这里用ehcache,在2.1中就是 hibernate.cache.provider_class=net.sf.hibernate.cache.EhCacheProvider假如使用查询缓存,加上hibernate.cache.use_query_cache=true

  缓存可以简单的看成一个Map,通过key在缓存里面找value。

  Class的缓存

  对于一条记录,也就是一个PO来说,是根据ID来找的,缓存的key就是ID,value是POJO。无论list,load还是iterate,只要读出一个对象,都会填充缓存。但是list不会使用缓存,而iterate会先取数据库select id出来,然后一个id一个id的load,假如在缓存里面有,就从缓存取,没有的话就去数据库load。假设是读写缓存,需要设置:

<cache usage="read-write"/>
  假如你使用的二级缓存实现是ehcache的话,需要配置ehcache.XML

<cache name="com.xxx.pojo.Foo" maxElementsInMemory="500" eternal="false" timeToLiveSeconds="7200" timeToIdleSeconds="3600" overflowToDisk="true" />
  其中eternal表示缓存是不是永远不超时,timeToLiveSeconds是缓存中每个元素(这里也就是一个POJO)的超时时间,假如eternal="false",超过指定的时间,这个元素就被移走了。timeToIdleSeconds是发呆时间,是可选的。当往缓存里面put的元素超过500个时,假如overflowToDisk="true",就会把缓存中的部分数据保存在硬盘上的临时文件里面。

  每个需要缓存的class都要这样配置。假如你没有配置,hibernate会在启动的时候警告你,然后使用defaultCache的配置,这样多个class会共享一个配置。

  当某个ID通过hibernate修改时,hibernate会知道,于是移除缓存。

  这样大家可能会想,同样的查询条件,第一次先list,第二次再iterate,就可以使用到缓存了。实际上这是很难的,因为你无法判定什么时候是第一次,而且每次查询的条件通常是不一样的,假如数据库里面有100条记录,id从1到100,第一次list的时候出了前50个id,第二次iterate的时候却查询到30至70号id,那么30-50是从缓存里面取的,51到70是从数据库取的,共发送1+20条sql。所以我一直认为iterate没有什么用,总是会有1+N的问题。

  (题外话:有说法说大型查询用list会把整个结果集装入内存,很慢,而iterate只select id比较好,但是大型查询总是要分页查的,谁也不会真的把整个结果集装进来,假如一页20条的话,iterate共需要执行21条语句,list虽然选择若干字段,比iterate第一条select id语句慢一些,但只有一条语句,不装入整个结果集hibernate还会根据数据库方言做优化,比如使用mysql的limit,整体看来应该还是list快。)

  假如想要对list或者iterate查询的结果缓存,就要用到查询缓存了

  查询缓存

  首先需要配置hibernate.cache.use_query_cache=true

  假如用ehcache,配置ehcache.xml,注重hibernate3.0以后不是net.sf的包名了:

<cache name="net.sf.hibernate.cache.StandardQueryCache"
maxElementsInMemory="50" eternal="false" timeToIdleSeconds="3600"
timeToLiveSeconds="7200" overflowToDisk="true"/>
<cache name="net.sf.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory="5000" eternal="true" overflowToDisk="true"/>
  然后

query.setCacheable(true);//激活查询缓存
query.setCacheRegion("myCacheRegion");//指定要使用的cacheRegion,可选
  第二行指定要使用的cacheRegion是myCacheRegion,即你可以给每个查询缓存做一个单独的配置,使用setCacheRegion来做这个指定,需要在ehcache.xml里面配置它:

<cache name="myCacheRegion" maxElementsInMemory="10" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="7200" overflowToDisk="true" />
  假如省略第二行,不设置cacheRegion的话,那么会使用上面提到的标准查询缓存的配置,也就是:net.sf.hibernate.cache.StandardQueryCache

  对于查询缓存来说,缓存的key是根据hql生成的sql,再加上参数,分页等信息(可以通过日志输出看到,不过它的输出不是很可读,最好改一下它的代码)。

  比如hql:


上一篇:新版JUnit 4.0 抢先体验 人气:703
下一篇:初学Java要注意什么 人气:563
浏览全部Java的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐