Hibernate缓存

1 Hibernate 缓存概述

        缓存是介于物理数据源与应用程序之间,是数据库数据在内存中的 存放临时 copy 的容器,

        其作用是为了减少应用程序对物理数据源访问的次数,从而提高了 应用的运行性能。

        Hibernate 在进行读取数据的时候,根据缓存机制在相应的缓存中查询,

        如果在缓存中找到了需要的数据 ( 我们把 这称做“缓存命中 ") ,则就直接把命中的数据作为结加   以利用,

        避免了建立数据库查询的性能损耗。

2 Hibernate 缓存分类

        一级缓存 (session): 内部缓存

                事务范围:缓存只能被当前事务访问。缓存的生命周期依赖于事务 的生命周期,

                当事务结束时,缓存也就结束生命周期。

        二级缓存 (sessionFactory): 缓存被应用范围内的所有事务共享。

                这些事务有可能是并发访问缓存,因此必须对缓存进行更新。

                缓存的生命周期依赖于应用的生命周期,应用结束时,

                缓存也就结束了生命周期,二级缓存存在于应用范围。

        集群范围:在集群环境中,缓存被一个机器或者多个机器的进程共 享。

                缓存中的数据被复制到集群环境中的每个进程节点,

                进程间通过远程通信来保证缓存中的数据的一致性,

                缓存中的数据通常采用对象的松散数据形式,二级缓存也存在与应用范围。

                注意:对大多数应用来说,应该慎重地考虑是否需要使用集群范围 的缓存,

                再加上集群范围还有数据同步的问题,所以应当慎用。

        多种范围的缓存处理过程

                持久化层可以提供多种范围的缓存。如果在事务范围的缓存中没有 查到相应的数据,

                还可以到应用范围或集群范围的缓存内查询,如果还是没有查到,那么只有到数据库中查了。

        缓存应用的范围 :

                修改少,数量在可以接受的范围内

5 、使用二级缓存的原则 :

        数据不会被第三方修改

        同一数据系统经常引用

        数据大小在可接受范围之内

        关键数据或不会被并发更新的数据

5 hibernate 引入第三方的缓存组件 EHCACHE ,下面是具体的实现步骤 :

        修改 hibernate.cfg.xml 配置引入 ehCache 缓存

                <hibernate-configuration>

                        <session-factory>

                                <property name="hibernate.cache.provider_class">

                                        net.sf.ehcache.hibernate.EhCacheProvider

                                </property>

                                <!--query 也支持缓存 -->

                                <property name="hibernate.cache.use_query_cache">true</property>

                        </session-factory>

                </hibernate-configuration>

        src 根目录下加入 ehcache.xml 文件,具体内容如下 :

                <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd">

                <defaultCache

                            maxElementsInMemory="10000"

                            eternal="false"

                            timeToIdleSeconds="120"

                            timeToLiveSeconds="120"

                            overflowToDisk="true"

                             />

                </ehcache>

        在映射文件中指定缓存同步策略

                <class name="com.tenly.bean.Student">

                        <cache usage="read-write">

                        <set name="classroom">

                                <cache usage="read-only">

                        </set>

                </class>

        usage 属性说明 :

            read-only: 只读。对于不会发生改变的数据,可使用只读型缓存。

            nonstrict-read-write: 不严格可读写缓存。如果应用程序对并发访问下的数据同步要求不是 很严格的话,

            而且数据更新操作频率较低。采用本项,可获得良好的性能。

            read-write

            对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可 以防止脏读这类的并发问题 .

            transactional (事物型)

            Hibernate 中,事务型缓存必须运行在 JTA 事 务环境中。

        在测试 query 时,说明其将用二级缓存

                query.setCacheable(true);

 

3 、释放缓存 :

        一级缓存的释放

                Session.evict(XXX)

                        将某个特定的对象从内部缓存中清除,上述的 XXX 为对象的实例名。使用此方法有两种适用情形,                        

                        需要及时释放对象占用的内存维持系统的稳定性

                        是不希望当前 Session 继续运用此对象的状态变化来同步更新数据库。

                Session.clear() 清除所有的一级缓存

        二级缓存的释放

                SessionFacatoyr.evict(XXX)

                        将某个特定的对象从内部缓存中清除,上述的 XXX 为对象的实例名。使用此方法有两种适用情形,                        

                        需要及时释放对象占用的内存维持系统的稳定性

                        是不希望当前 Session 继续运用此对象的状态变化来同步更新数据库。

                SessionFactory.clear() 清除所有的二级缓存

6 、查询缓存:

        二级缓存策略的一般过程:

            Hibernate 进行条件查询的时候,总是发出一条 select * from XXX where …( XXX 表名,

             类似的语句下文统称 Select SQL )这样的 SQL 语句查询数据库,一次获得所有的符合条件的数据对象。

                把获得的所有数据对象根据 ID 放入 到第二级缓存中。

                Hibernate 根据 ID 访问数据对象的时候,首先从内部缓存中查找,如果在内部缓存中 查不到就配置二级缓存,

                从二级缓存中查;如果还查不到,再查询数据库,把结果按照 ID 放 入到缓存。

             添加数据、删除、更新操作时,同时更新二级缓存。这就是 Hibernate 做批处理的时候效率不高的原因,

                     原来是要维护二级缓存消耗大量时间的缘故。

    条 件查询的处理过程:

                第一次查找 age>20 的所有学生信息,然后纳入二级缓存。

                第二次我们的查询条 件变了,查找 age>15 的所有学生信息,显然第一次查询的结果完全满足第二次查询的条 件,

                但并不是满足条件的 全部数据。这样的话,我们就要再做一次查询得到全部数据才行。

                如果我们执行的是相 同的条件语句, Hibernate 引入 Query Cache 的。

             查询缓存策略的一般过程:

                        完全相同的 Select SQL 重复执行。

                        重复执行期间, Query Key 对应的数据表不能有数据变动(比如添、删、改操作)

                        启用 Query Cache ,我们需要在 hibernate.cfg.xml 中进行配置,参考配置如下(只列出核心配置项):

                                <hibernate-configuration>

                                        <session-factory>

                                                <property name="hibernate.cache.user_query_cache">true</property>

                                        </session-factory>

                                </hibernate-configuration>

                        在查询执行之前,将 Query.Cacheable 设置为 true, 而且每次都应该这样。比如 :

                                Query query=session.createQuery(hql).setInteger(0.15);

                                query.setCacheable(true);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值