hibernate缓存的学习(二)

2015-07-24 06:55:55 · 作者: · 浏览: 1
erator是可以从缓存当中读取数据的,如果使用iterator查询所有数据,会首先查询所有的id,然后根据id一次发出sql语句,查询每一条记录,这样无形当中就降低了查询效率,那么我们可以根据这些特性,将list查询和iterator查询结合起来使用。
我们可以首先使用list查询所有,这样只会发出一条查询语句,不必想iterator那样发出n+1条sql语句,提升了查询效率,第一次之后查询所有数据的时候,就可以直接使用iterator来查询,这样可以只查询所有的id,然后根据id从缓存当中取数据,代码如下:

String hql = "from UserInfo";
Listlists = session.createQuery(hql).list();
for (UserInfo userInfo : lists) {
    System.out.println(userInfo.getUserName());
}
Iteratoritertor = session.createQuery(hql).iterate();
while (itertor.hasNext()) {
            System.out.println(itertor.next().getUserName());
}

此时hibernate发出的sql和我们预期的一样:
这里写图片描述

hibernate二级缓存

在hibernate中,二级缓存默认是打开的,一般来讲,hibernate的二级缓存是和应用的生命周期是一样的,由于二级缓存的数据每一个session都可以进行访问和更改,所以如果出现高并发的时候,有可能会出现问题。
1.添加ecache所需的jar文件:
在hibernate-release-4.3.10.Final\lib\optional\ehcache目录下有这样三个jar文件,需要加入到工程中:
slf4j-api-1.6.1.jar
hibernate-ehcache-4.3.10.Final.jar
ehcache-core-2.4.3.jar
2.配置二级缓存:
在hibernate.cfg.xml文件中进行配置:



    org.hibernate.cache.EhCacheProvider


true

所谓查询缓存就是让hibernate缓存list,iterator,createQuery等方法的查询结果集,如果没有打开查询缓存,hibernate将只缓存load方法获得的单个持久化对象。
注意:在打开查询缓存 之后,调用query.list()之前,必须显示调用query.setCacheable(true)来标识该查询使用缓存。
3.建立ehcache.xml,在类路径下:


  
      
    

说明一下:
diskStore表示设置cache文件的存放目录,有如下三种配置:
1.user.home 表示用户的主目录
2.user.home 表示用户当前的工作目录
3.java.io.tmpdir 默认的temp文件目录
maxElementsInMemory :在内存中最大的对象缓存数量
eternal :设置是否为永久缓存,如果是永久缓存,则timeout将被忽略。
可选的属性:
timeToIdleSeconds:表示设置元素过期前的空闲时间
timeToLiveSeconds:表示设置元素过期前的活动时间
diskPersistent:表示是否disk store在虚拟机启动时持久化。默认为false
diskExpiryThreadIntervalSeconds:表示运行disk终结线程的时间,默认为120秒
memoryStoreEvictionPolicy:表示策略关于Eviction
4.配置映射文件
在需要被缓存的类对应的映射文件中配置hibernate的缓存策略

这里我配置的缓存策略是可读写的。该配置有如下一些值:
1.read-only :表示无需修改的数据。
2.read-write :需要更新数据
3.nonstrict-read-write 非严格读写缓存策略。只需要偶尔更新数据,并且也不需要十分严格的事物隔离。
5.编写测试代码:

Query query = session.createQuery("from UserInfo");
query.setCacheable(true)
List list = query.list();
for (UserInfo userinfo : list) {
    System.out.println(userinfo.getUid()+"---"+userinfo.getUname());
}
session.close();
Session session2 = sf.openSession();
UserInfo userinfo =(UserInfo)session2.get(UserInfo.class, 1);       System.out.println(userinfo.getUid()+"***"+userinfo.getUname());

这里,虽然第一次查询完成后session就已经关闭,但是由于配置了二级缓存,所以当session2再次查询的时候,是不需要再发出sql语句从数据库当中查询的。

关于hibernate的缓存的学习就到这里了。