一级缓存、二级缓存、查询缓存

一级缓存(firstCache):线程级别

1):Session 级别的缓存,与session邦定。它的生命周期和session相同。
Session消毁,它也同时消毁;管理一级缓存,一级缓存无法取消
2):两个Session 不能共享一级缓存,因它会伴随session的生命周期的创建和消毁;
3):get使用了一级缓存,用get查数据时,首先检查缓存中是否有该数据,如果有直接从缓存中取数据,如果没有再查询数据库,并且将数据放入缓存中。
load也支持一级缓存。load还支持lazy.当load从数据库中查询数据后,也会将数据放入缓存。
unique/list查询不会去查看缓存,但是list查询的实体对象将会放入缓存中。
4):与一级缓存相关方法:
session.clear():清除一级缓存中所有的对象。
boolean contains(Object entity):判断一级缓存中是否有给定的对象。
session.evict(Object entity):从一级缓存中清除指定的对象。
session.flush():把一级缓存中的脏数据同步到数据库中。
session.refresh((Objectentity):强制重新查询对象,相当于把数据库中的数据同步到一级缓存中。

二级缓存(SecondCache)

1,生命周期为整个应用的缓存(二级缓存是sessionFactory上的缓存,能提供整个应用中所有的session使用。)
2,所有的get,load方法,总是先查一级缓存,再查二级缓存,如果都没有,在去数据库里面查询。
3,不是所有的对象都适合放到二级缓存中。
通常情况下会放入到二级缓存中情况:
● 经常查询的数据 。
● 很少被修改的数据。
● 不会被并发访问的数据。
不适合放在二级缓存中的情况:
● 经常被修改的数据
4,二级缓存有一些性能相关属性:
1,命中率(总的从二级缓存中取得的数量/总的取的数量)
2,最大对象数量;
3,最大空闲时间;
5,二级缓存实际上就是一个缓存,所以,hibernate并没有实现自己的二级缓存框架,而是用的开源的

EHCache的配置和应用:

使用EHCache的准备:
1,导入对应的二级缓存jar包.
ehcache-core-2.4.3.jar
hibernate-ehcache-4.3.5.Final.jar
slf4j-api-1.6.1.jar

配置ehcache.xml文件
<ehcache>
    <!--
        指定一个目录:当 EHCache 把数据写到硬盘上时, 将把数据写到这个目录下.
    -->
    <diskStore path="d:\\tempDirectory"/>

    <!--
        设置缓存的默认数据过期策略
    -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
    />

    <!--
        设定具体的命名缓存的数据过期策略。每个命名缓存代表一个缓存区域
        缓存区域(region):一个具有名称的缓存块,可以给每一个缓存块设置不同的缓存策略。
        如果没有设置任何的缓存区域,则所有被缓存的对象,都将使用默认的缓存策略。即:<defaultCache.../>
        Hibernate 在不同的缓存区域保存不同的类/集合。
         对于类而言,区域的名称是类名。如:com.atguigu.domain.Customer
         对于集合而言,区域的名称是类名加属性名。如com.atguigu.domain.Customer.orders
    -->
    <!--
        name: 设置缓存的名字,它的取值为类的全限定名或类的集合的名字
        maxElementsInMemory: 设置基于内存的缓存中可存放的对象最大数目

        eternal: 设置对象是否为永久的, true表示永不过期, 此时将忽略timeToIdleSeconds 和 timeToLiveSeconds属性; 默认值是false
       timeToIdleSeconds:设置对象空闲最长时间,以秒为单位, 超过这个时间,对象过期。当对象过期时,EHCache会把它从缓存中清除。如果此值为0,表示对象可以无限期地                  处于空闲状态。
        timeToLiveSeconds:设置对象生存最长时间,超过这个时间,对象过期。如果此值为0,表示对象可以无限期地存在于缓存中.
                该属性值必须大于或等于 timeToIdleSeconds 属性值

        overflowToDisk:设置基于内存的缓存中的对象数目达到上限后,是否把溢出的对象写到基于硬盘的缓存中
    -->
    <cache name="com.qy.domain.Province"
           maxElementsInMemory="1"
           eternal="false"
           timeToIdleSeconds="300"
           timeToLiveSeconds="600"
           overflowToDisk="true"
    />

</ehcache>

在hibernate.cfg.xml配置如下

 <!--使用二级缓存-->
        <property name="hibernate.cache.use_second_level_cache">true</property>
        <!--配置二级缓存服务商-->
        <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
        <!--使用查询缓存-->
        <property name="cache.use_query_cache">true</property>
 		 <!--配置读写-->
        <class-cache class="com.qy.domain.Province" usage="read-write"></class-cache>

测试代码

/*一级缓存 Session
 * 二级缓存 SessionFactory
 * 查询缓存 createQuery*/
public class TestCache {
     /*
    一级缓存  get,load方法自动从一级缓存中查找,如果存在缓存对象,直接使用
     */
     @Test
     public void firstLevel(){
         Session session = HibernateUtill.getCurrentSession();

         Province p = session.get(Province.class,1);

         Province p1 = session.get(Province.class,1);

       HibernateUtill.sessionClose(session);
     }

    @Test
    public void sendcondLevel(){
        Session session = HibernateUtill.getCurrentSession();

        Province p = session.get(Province.class,1);
        HibernateUtill.sessionClose(session);

        Session session1 = HibernateUtill.getCurrentSession();
        Province p1 = session1.get(Province.class,1);

        HibernateUtill.sessionClose(session1);
    }

    @Test
    public void quaryLevel(){
        Session session = HibernateUtill.getCurrentSession();

        List<Province> list = session.createQuery("from Province").setCacheable(true).list();
        HibernateUtill.sessionClose(session);

        Session session1 = HibernateUtill.getCurrentSession();
        List<Province> list2 = session1.createQuery("from Province").setCacheable(true).list();

        HibernateUtill.sessionClose(session1);
    }

查询缓存实现原理

一级缓存和二级缓存都是对实体对象进行缓存,而查询缓存是针对于实体对象的属性.开发中一般不使用查询缓存,可能会降低系统性能.
1,使用查询缓存的前提;
1,HQL不能变;
2,查询参数不能变;
3,查询缓存结果类型中,如果有其他的事务(线程)更新过相同的类型,那么所有关 于这个类型的查询缓存全部失效
2,查询缓存执行流程:
1,缓存HQL和对应的参数值;
2,把查询结果对应的对象id序列保存到查询缓存中;
3,遍历缓存,去加载每一个对象
3, 使用用查询缓存:
1,默认情况查询缓存关闭,手动开启
设置hibernate.cache.use_query_cache=true
2,在查询的时候query对象.setCacheable(true)

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值