二级缓存

二级缓存

与Session相对的是,SessionFactory也提供了相应的缓存机制。SessionFactory缓存可以依据功能和目的的不同而划分为内置缓存和外置缓存。

SessionFactory的内置缓存中存放了映射元数据和预定义SQL语句,映射元数据是映射文件中数据的副本,而预定义SQL语句是在Hibernate初始化阶段根据映射元数据推导出来的。SessionFactory的内置缓存是只读的,应用程序不能修改缓存中的映射元数据和预定义SQL语句,因此SessionFactory不需要进行内置缓存与映射文件的同步。SessionFactory的外置缓存是一个可配置的插件。在默认情况下,SessionFactory不会启用这个插件。外置缓存的数据是数据库数据的副本,外置缓存的介质可以是内存或者硬盘。SessionFactory的外置缓存也被称为Hibernate的二级缓存。Hibernate的二级缓存的实现原理与一级缓存是一样的,也是通过以ID为key的Map来实现对对象的缓存。由于Hibernate的二级缓存是作用在SessionFactory范围内的,因而它比一级缓存的范围更广,可以被所有的Session对象所共享二级缓存的实现原理:

从数据库里查询得到的类对象,根据这个类的id把它保存到一个map的集合里,这个id作为key,而这个对象实例作为value,而这个map的生命周期是sessionfactroy范围里的,这样,当我们想要从缓存里拿对象时,根据查询的id直接去map里拿对应的value(也就是对象实例)。

二级缓存的工作内容

1.在配置好二级缓存的情况下,包括指定那个类可以被保存到二级缓存里,这时从数据库里查询得到的类对象,hibernate将它保存到二级缓存里;

2.当hibernate根据Id 查询对象时,会先从一级缓存里找(也就是session里找),如果找不到并且配置了二级缓存,那么hibernate 会去二级缓存里找,如果还找不到,那么就根据id 直接查询数据库。

二级缓存的适用范围

适合于:

1.很少要修改的数据;这种即使并发也不怕

2.不并发的数据

如:某些数据是属于一个用户所有,那么这些数据放在二级缓存里,虽然是共享,但别人是不会使用到你的数据的,因为查询数据库使用的id 是不同的

不适合

1 经常被修改的数据。

2 财务数据,绝对不允许出现并发。

3 与其他应用共享的数据

二级缓存的配置

hibernate  默认关闭二级缓存的,要使用必须进行如下配置:

1. 、首先设置EhCache,建立配置文件ehcache.xml,默认的位置在class-path,可以放到你的src目录下:

<ehcache>
    <diskStore path="java.io.tmpdir"/>
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        overflowToDisk="true"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        diskPersistent="false"
        />
</ehcache>

属性说明:
        maxElementsInMemory属性用于指定缓存中最多可放多少个对象。
        eternal属性指定缓存是否永久有效。
        timeToIdleSeconds属性指定缓存多久未被使用便清理掉。
        timeToLiveSeconds属性指定缓存的生命长度。
       diskPersistent属性指定缓存是否被持久化到硬盘中,保存路径由<diskStore>标签指定。

2.修改hibernate.cfg.xml文件设置二级缓存。

<hibernate-configuration>
    <session-factory>
          <!-- 设置缓存提供者 -->
        <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
        <mapping resource="cn/ineeke/entity/User.hbm.xml"/>
    </session-factory>
</hibernate-configuration>
 说明:可以通过设置hibernate.cache.provider_class属性,指定其他的缓存策略(也就是实现类),该缓存策略必须实现   org.hibernate.cache.CacheProvider接口。

通过实现org.hibernate.cache.CacheProvider接口可以提供不同二级缓存组件的支持

表14.1    Hibernate所支持的二级缓存组件

 

组件

Provider类

类型

集群

查询缓存

Hashtable

org.hibernate.cache.HashtableCacheProvider

内存

不支持

支持

EHCache

org.hibernate.cache.EhCacheProvider

内存,硬盘

不支持

支持

OSCache

org.hibernate.cache.OSCacheProvider

内存,硬盘

不支持

支持

SwarmCache

org.hibernate.cache.SwarmCacheProvider

集群

支持

不支持

JBoss TreeCache

org.hibernate.cache.TreeCacheProvider

集群

支持

支持

 

3.指定哪些实体类会被保存到二级缓存。经过第二步缓存是启用了,但是并没有被使用。它不会去自动把所有的实体都进行缓存了,而是需要手动指定哪个实体需要缓存,以及其缓存的策略。

在User.hbm.xml中使用<cache>标签启用。
<hibernate-mapping>
    <class name="cn.ineeke.entity.User" table="t_user">
        <cache usage="read-only"/>
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="name"/>
    </class>
</hibernate-mapping>
注意:这里的<cache>标签一定要放在 <id >标签的前面

4. 到了这里hibernate只会缓存使用load()方法获得的单个持久化对象,如果想缓存使用list()、Iterator()、createCriteria()、createQuery()等方法获得的数据结果集的话,就需要在hibernate.cfg.xml添加
<property name="hibernate.cache.use_query_cache">true</property>

 

5.测试用例:

 先在session里load()一个对象,接着关闭session用相同的id 再load()这个对象,第二次在控制台没有看到查询的sql语句

 

 

 

注意:

a.sessionfactroy的生命周期是在初始化后直到服务器关闭,

b.第一次load这个对象后,(这个对象在二级缓存里有限制存活多久的,在上面的<ehcache>里配置,)如果在这个时间内,那么直接可以拿到。



 




 



 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值