Hibernate教程之八二级缓存

Hibernate使用二级缓存,Hibernate本身没有实现二级缓存,所以我们都是使用的第三方的缓存,这里只是介绍使用Ehcache缓存
使用步骤:
1、引用jar包
eh'ca'che缓存的jar包
2、引用配置文件ehcache.xml

<!--ehcache二级缓存的配置信息-->
<ehcache>

    <!-- 如果二级缓存的数量超出的存储的磁盘路径 -->
    <diskStore path="G:/cache"/>


    <!--
        默认的配置
        maxInMemory -设置内存存储的最大数量
        eternal     -设置二级缓存中缓存对象的是否永久有效,一般都是false 
        timeToIdleSeconds -空闲时间,设置缓存对象的最大空闲时间,单位秒
        timeToLiveSeconds -生命周期,设置对象的存活时间,超出更新缓存内容
        overflowToDisk    -如果缓存对象的数量超出设置的内存最大数量,将超出存储到磁盘
        -->
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
        />

    <!--Predefined caches.  Add your cache configuration settings here.
        If you do not have a configuration for your cache a WARNING will be issued when the
        CacheManager starts

        The following attributes are required for defaultCache:

        name              - Sets the name of the cache. This is used to identify the cache. It must be unique.
        maxInMemory       - Sets the maximum number of objects that will be created in memory
        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
                            is never expired.
        timeToIdleSeconds - Sets the time to idle for an element beforeQuery it expires. Is only used
                            if the element is not eternal. Idle time is now - last accessed time
        timeToLiveSeconds - Sets the time to live for an element beforeQuery it expires. Is only used
                            if the element is not eternal. TTL is now - creation time
        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
                            has reached the maxInMemory limit.

        -->

    <!-- Sample cache named sampleCache1
        This cache contains a maximum in memory of 10000 elements, and will expire
        an element if it is idle for more than 5 minutes and lives for more than
        10 minutes.

        If there are more than 10000 elements it will overflow to the
        disk cache, which in this configuration will go to wherever java.io.tmp is
        defined on your system. On a standard Linux system this will be /tmp"
        -->
    <cache name="sampleCache1"
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="600"
        overflowToDisk="true"
        />

    <!-- Sample cache named sampleCache2
        This cache contains 1000 elements. Elements will always be held in memory.
        They are not expired. -->
    <cache name="sampleCache2"
        maxElementsInMemory="1000"
        eternal="true"
        timeToIdleSeconds="0"
        timeToLiveSeconds="0"
        overflowToDisk="false"
        /> -->

    <!-- Place configuration for your caches following -->

</ehcache>
``
3、在hibernate.cfg.xml中启用二级缓存并配置


true


org.hibernate.cache.ehcache.EhCacheRegionFactory

true

4、在类的mapping文件中添加二级缓存的使用



注意:cache标签只能出现在class的下面和id的上面

5、测试就可以了
oid操作基本上都会操作二级缓存
而HQL操作默认不会操作二级缓存,想要操作需要开启查询缓存
query.setCacheable(true)

测试代码:

//缓存
public class MyTest {

private Session session;
private Transaction tran;

// 每次执行单元测试的时候,都会优先执行
@Before
public void bre() {
    session = HibUtils.getSession();
    tran = session.beginTransaction();
}

// 验证一级缓存的存在
@Test
public void test1() {
    // 会发起SQL
    Cource cource = session.get(Cource.class, 1);
    // 不会发起SQL
    Cource cource3 = session.get(Cource.class, 1);
    session.evict(cource);// 移除
    // 再次发起SQL语句
    Cource cource2 = session.get(Cource.class, 1);
    Session session2 = HibUtils.openSession();

    System.out.println("第一个:" + session.hashCode());
    System.out.println("第二个:" + session2.hashCode());
    // 创建另外的Session
    Cource cource4 = session2.get(Cource.class, 1);

}

// 二级缓存:存储在SessionFactory
// oid操作会存储到二级缓存中
@Test
public void test2() {
    Session session1 = HibUtils.openSession();
    Session session2 = HibUtils.openSession();
    System.out.println("1:" + session1.hashCode());
    System.out.println("2:" + session2.hashCode());
    Cource cource1 = session1.get(Cource.class, 1);
    // 不会发起SQL语句,因为有二级缓存
    Cource cource2 = session2.get(Cource.class, 1);
    SessionFactory factory = HibUtils.getFactory();

    System.out.println(factory.getStatistics().getSecondLevelCachePutCount());
}

// HQL\SQL\QBC会不会跟二级缓存
@Test
public void test3() {
    String hql = "from Cource ";
    Session session1 = HibUtils.openSession();
    Session session2 = HibUtils.openSession();
    // 不使用查询缓存
    Query<Cource> query1 = session1.createQuery(hql);
    Cource cource1 = query1.getSingleResult();//
    Query<Cource> query2 = session1.createQuery(hql);
    Cource cource2 = query2.getSingleResult();
    System.out.println(cource1 == cource2);// true
    // 开启2次sql查询
    // 无论是否使用查询缓存当查询结果返回时都会经过一级缓存,这时如果存在那么就不会新建对象

    // 使用查询缓存---使用二级缓存
    Query<Cource> query3 = session1.createQuery(hql);
    query3.setCacheable(true);
    Cource cource3 = query3.getSingleResult();
    Query<Cource> query4 = session2.createQuery(hql);
    query4.setCacheable(true);
    Cource cource4 = query4.getSingleResult();
    System.out.println(cource3 == cource4);// false
    // 开启一次SQL查询
    // 因为查询需要检索二级缓存,重新创建对象

}
//演示查询结果的路径,是否走一级缓存或二级缓存
@Test
public void test4() {
    String hql = "from Cource where id=1 ";
    Session session1 = HibUtils.openSession();
    Session session2 = HibUtils.openSession();
    // 使用查询缓存---使用二级缓存
    Query<Cource> query3 = session1.createQuery(hql);
    query3.setCacheable(true);
    Cource cource3 = query3.getSingleResult();
    Query<Cource> query4 = session2.createQuery("from Cource");
    query4.setCacheable(true);
    List<Cource> list = query4.getResultList();
    System.out.println("单个:id=1:"+cource3.hashCode());
    System.out.println("第二次:id=1:" +list.get(0).getId()+"---->"+
    list.get(0).hashCode());

}

// 每次只需单元测试的时候,都会最后执行
@After
public void aft() {
    tran.commit();
}
}

“`
使用二级缓存要小心,对于频繁改变的数据和特别敏感的数据都不要使用二级缓存。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值