Hibernate缓存管理 2

++YONG原创,转载请注明
配置的元素说明:
元素或属性
描述
<diskStore>
设置缓存数据文件的存放目录
<defaultCache>
设置缓存的默认数据过期策略
<cache>
设定具体的命名缓存的数据过期策略
每个命名缓存代表一个缓存区域,每个缓存区域有各自的数据过期策略。命名缓存机制使得用户能够在每个类以及类的每个集合的粒度上设置数据过期策略。
cache元素的属性
 
name
设置缓存的名字 , 它的取值为类的全限定名或类的集合的名字
maxInMemory
设置基于内存的缓存中可存放的对象最大数目
eternal
设置对象是否为永久的 ,true 表示永不过期 , 此时将忽略 timeToIdleSeconds timeToLiveSeconds 属性 ;
默认值是 false
timeToIdleSeconds
设置对象空闲最长时间 , 超过这个时间 , 对象过期。当对象过期时 ,EHCache 会把它从缓存中清除。
如果此值为 0, 表示对象可以无限期地处于空闲状态。
timeToLiveSeconds
设置对象生存最长时间 , 超过这个时间 , 对象过期。
如果此值为 0, 表示对象可以无限期地存在于缓存中。
overflowToDisk
设置基于内在的缓存中的对象数目达到上限后 , 是否把溢出的对象写到基于硬盘的缓存中
 
3)      写一测试类:
package org.qiujy.test.cache;
 
import java.util.List;
 
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.qiujy.common.HibernateSessionFactory;
import org.qiujy.domain.cachedemo.Product;
 
public class TestCache {
 
       public static void main(String[] args) {
       
              //test cache.........
              Session session2 = HibernateSessionFactory.getSession();
              Transaction tx2 =null;
             
              try{
                     tx2 = session2.beginTransaction();
                    
                     List list = session2.createQuery("from Product").list();
                    
                     for(int i = 0 ; i < list.size(); i++){
                            Product prod = (Product)list.get(i);
                            System.out.println(prod.getName());
                     }
                    
                    tx2.commit();
              }catch(HibernateException e){
                     if(tx2 != null){
                            tx2.rollback();
                     }
                     e.printStackTrace();
              }finally{
                     HibernateSessionFactory.closeSession();
              }
             
              //-------------------
              Session session3 = HibernateSessionFactory.getSession();
              Transaction tx3 =null;
             
              try{
                     tx3 = session3.beginTransaction();
                    
                     Product prod = (Product)session3.get(Product.class, new Long(1));
                     System.out.println("从cache中得到,不执行SQL---" + prod.getName());
                 
                    tx3.commit();
              }catch(HibernateException e){
                     if(tx3 != null){
                            tx3.rollback();
                     }
                     e.printStackTrace();
              }finally{
                     HibernateSessionFactory.closeSession();
              }
       }
}
首先数据库插入1000条产品记录和1条类别记录。此1000个产品都属于这一类别。然后执行以上测试类,在Session2中查询所有的产品,输出它的产品名,Session2会把这些数据加载到二级缓存中,由于有1000个对象,而配置中定义内存中只能存放500个,剩下的对象就会写到指定的磁盘目录中缓存起来。所以在磁盘相应位置可看到数据文件:
2.5.    查询缓存(Query Cache)
对于经常使用的查询语句,如果启用了查询缓存,当第一次执行查询语句时,Hibernate会把查询结果存放在第二缓存中。以后再次执行该查询语句时,只需从缓存中获得查询结果,从而提高查询性能。
2.5.1.      查询缓存适用于以下场合:
l 在应用程序运行时经常使用的查询语句。
l 很少对与查询语句关联的数据库数据进行插入、删除或更新操作。
2.5.2.      Hibernate Query 缓存策略的过程如下:
1) Hibernate首先根据这些信息组成一个Query Key,Query Key包括条件查询的请求一般信息:SQL, SQL需要的参数,记录范围(起始位置rowStart,最大记录个数maxRows),等。
2) Hibernate根据这个Query Key到Query缓存中查找对应的结果列表。如果存在,那么返回这个结果列表;如果不存在,查询数据库,获取结果列表,把整个结果列表根据Query Key放入到Query缓存中。
3) Query Key中的SQL涉及到一些表名,如果这些表的任何数据发生修改、删除、增加等操作,这些相关的Query Key都要从缓存中清空。
只有当经常使用同样的参数进行查询时,这才会有些用处。
启用查询缓存的步骤:
1)      配置二级缓存:
Hibernate提供了三种和查询相关的缓存区域:
l 默认的查询缓存区域:org.hibernate.cache.StandardQueryCache
l 用户自定义的查询缓存区域:
l 时间戳缓存区域:org.hibernate.cache.UpdateTimestampCache
默认的查询缓存区域以及用户自定义的查询缓存区域都用于存放查询结果。而时间戳缓存区域存放了对与查询结果相关的表进行插入、更新或删除操作的时间戳。Hibernate通过时间戳缓存区域来判断被缓存的查询结果是否过期。所以,当应用程序对数据库的相关数据做了修改,Hibernate会自动刷新缓存的查询结果。但是如果其他应用程序对数据库的相关数据做了修改,则无法监测,此时必须由应用程序负责监测这一变化,然后手工刷新查询结果。Query接口的setForceCacheRefresh(true)可以手工刷新查询结果。
在ehcache.xml中添加如下配置:
<!-- 设置默认的查询缓存的数据过期策略 -->
    < cache name = "org.hibernate.cache.StandardQueryCache"
       maxElementsInMemory = "50"
       eternal = "false"
       timeToIdleSeconds = "3600"
       timeToLiveSeconds = "7200"
       overflowToDisk = "true" />
        
    <!-- 设置时间戳缓存的数据过期策略 -->
    < cache name = "org.hibernate.cache.UpdateTimestampsCache"
       maxElementsInMemory = "5000"
       eternal = "true"
       overflowToDisk = "true" />
   
    <!-- 设置自定义命名查询缓存 customerQueries 的数据过期策略 -->
    < cache name = "myCacheRegion"
        maxElementsInMemory = "1000"
        eternal = "false"
        timeToIdleSeconds = "300"
        timeToLiveSeconds = "600"
        overflowToDisk = "true"
        />
 
2)      打开查询缓存:在hibernate.cfg.xml添加如下配置
<!-- 启用查询缓存 -->
< property name = "cache.use_query_cache" > true </ property >
 
3)      在程序中使用:
虽然按以上设置好了查询缓存,但Hibernate在执行查询语句语句时仍不会启用查询缓存。对于希望启用查询缓存的查询语句,应该调用Query接口的setCacheeable(true)方法:
       测试类如下:
package org.qiujy.test.cache;
 
import java.util.List;
 
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.qiujy.common.HibernateSessionFactory;
import org.qiujy.domain.cachedemo.Product;
 
public class TessQueryCache {
 
       public static void main(String[] args) {
              Session session = HibernateSessionFactory.getSession();
              Transaction tx =null;
             
              try{
                     tx = session.beginTransaction(); 
                     Query query = session.createQuery("from Product");
                     // 激活查询缓存
                     query.setCacheable(true);
                     // 使用自定义的查询缓存区域 , 若不设置 , 则使用标准查询缓存区域
                     query.setCacheRegion("myCacheRegion");
                    
                     List list = query.list();
                     for(int i = 0 ; i < list.size(); i++){
                            Product prod = (Product)list.get(i);
                            System.out.println(prod.getName());
                     }
                    
                    tx.commit();
              }catch(HibernateException e){
                     if(tx != null){
                            tx.rollback();
                     }
                     e.printStackTrace();
              }finally{
                     HibernateSessionFactory.closeSession();
              }
       }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值