hibernate 二级缓存(一)

转自http://terryjs.iteye.com/blog/751444

一。

1 Hibernate 二级缓存也称之为进程级或 SessionFactory 级缓存。

 

2 生命周期:

SessionFactory 生命周期一致。

 

3 缓存类型:

只缓存对象实体,不缓存普通属性。

 

4 缓存范围:

可被所有 session 共享。

 

5 缓存配置:

需要 ehcache.jar (第 3 方缓存产品)和 ehcache.xml ehcache 不支持分布式缓存。

 

6. 缓存管理:

       SessionFactory 可以直接对二级缓存进行管理。

           // 清空二级缓存中某个对象的所有数据

           evict( 类名 . class );

           // 清空二级缓存中某个对象某一列的数据

           evict( 类名 . class , id);

 

7 优点:

减小(少)数据库压力以及访问次数。

 

8 缺点:

不易缓存经常变更的数据,因为数据库数据发生改变时缓存内的数据 不能及时 同步。二级缓存的 / 写缓存策略虽然支持数据库和缓存数据同步,但效率不高:

缓存经常变更的数据虽降低数据库的访问次数,但长时间持续缓存这些数据却增加了 Hibernate 本身的压力和数据库的任务量:

01.    更新数据库数据。

02.    同步对象锁,避免其他事务访问。

03.    更新缓存内记录。

采用缓存其实就是利用缓存消亡前的时间差的间隙来获取数据,即可缓解数据库的访问次数和压力,但对于读写策略来说却降低了效率。

 

9 开启二级缓存:在 Hibernate 配置文件利添加:

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

true

</ property >

 

10 指定缓存提供商:

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

org.hibernate.cache.EhCacheProvider

</ property >

 

11. 缓存策略:

只读缓存( read only ):当数据库数据发生改变时,缓存内的数据不会和数据库同步 , 一般推荐使用只读缓存(缓存消亡后仍重新更新数据)。

      Hibernate 配置文件 <mapping/> 标签后配置:

< class-cache class = " 包名 . 类名 " usage = "read-only" />

 

/ 写缓存( read/write ):

当数据库数据发生改变时,缓存内的数据可以和数据库同步 , 一般不建议使用。原因就在于会带给 Hibernate 很大的压力和数据库大任务量。

Hibernate 配置文件 <mapping/> 标签后配置:

< class-cache class = " 包名 . 类名 " usage = "read-write" />

 

    如果是在 cfg 里面配置缓存策略,那么必须在 <mapping/> 标签后配置, hbm <id/> 属性标签前配置。

 

12. ehcache.xml 配置文件信息:

                  <!-- 内存不足时,磁盘缓存目录 -->

                  < diskStore path = "c:/WINDOWS" />

                  < defaultCache

            <!-- 缓存中最大允许创建的对象数 -->

           maxElementsInMemory = "10000"

           <!-- 缓存中对象是否为永久的,如果是,缓存将不消亡 -->

           eternal = "false"

           <!-- 缓存数据钝化时间 ( 设置缓存在消亡之前的空闲时间 )-->

           timeToIdleSeconds = "120"

           <!-- 缓存数据的生存时间 ( 设置缓存超过这个时间就消亡 )-->

           timeToLiveSeconds = "120"

             <!-- 内存不足时,是否启用磁盘缓存 -->

           overflowToDisk = "true"

        />

 

13. 一级缓存和二级缓存交互:

    session 关闭后,一级缓存也就消亡了,这个时候如果二级缓存已开启,那么就会从二   级缓存里面获取数据,而不会重新访问数据库来获取。

    Hibernate 配置文件信息里,添加对二级缓存的支持:

       <!-- 启动二级缓存 -->

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

            true

       </ property >

       <!-- 指定缓存提供商 -->

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

           org.hibernate.cache.EhCacheProvider

       </ property >

       < mapping resource = "com/bean/User.hbm.xml" />

       <!-- 采用只读策略 -->

       < class-cache class = "com.bean.User" usage = "read-only" />

 

缓存交互代码:

    public void testGet()

    {

       Session session = null ; // 声明 Session 接口

       try

       {

           // 打开 session

           session = Hibernate_Utils.getFactory ().openSession();                

           session.beginTransaction(); // 打开事务

           Query query = session.createQuery( "select u from User u where u.id = '1'" );

           List list = query.list();

           Iterator iter = list.iterator();

           while (iter.hasNext())

           {

              User user = (User)iter.next();

              System. out .println( " 数据库数据: " + user.getName());

           }

           // 加载 session get 方法

           User user = (User)session.get(User. class , 1);

           System. out .println( " 一级缓存数据: " + user.getName());

           session.getTransaction().commit(); // 提交事务

       }

       catch (Exception e)

       {

           e.printStackTrace();

           session.getTransaction().rollback(); // 回滚事务

           return ;

       }

       finally

       {

           if (session != null )

           {

              session.close(); // 结束资源

           }

       }

       try

       {

           // 打开 session

           session = Hibernate_Utils.getFactory ().openSession();                

           session.beginTransaction(); // 打开事务

           // 加载 session load 方法

           User user = (User)session.load(User. class , 1);

           System. out .println( " 二级缓存数据: " + user.getName());

           session.getTransaction().commit(); // 提交事务

       }

       catch (Exception e)

       {

           e.printStackTrace();

           session.getTransaction().rollback(); // 回滚事务

           return ;

       }

       finally

       {

           if (session != null )

           {

              session.close(); // 结束资源

           }

       }

    }   

上面采用的缓存策略是 read-only (只读) , 只读策略是不允许对数据库数据进行修改(非手动修改数据库数据)也不会和数据库数据同步(只有缓存消亡后会重新获取数据),否则会抛出 java.lang.UnsupportedOperationException 异常。

采用 read-write (读写)策略也是不允许手动修改数据库数据的,否则是看不见效果的。

 

二。

缓存( Cache ),往往是提高系统性能的重要手段。对数据起到一个蓄水池和缓冲的的作用。缓存对于大量依赖数据读取操作的系统而言尤为重要,在大并发量的情况下,如果每次程序都需要向数据库直接做查询操作,所带来的性能开销显而易见。频繁的网络传输、数据库磁盘的读写操作,这些都大大降低了系统的整体性能。此时,如果能把数据在本地内存中保留一个镜像,下次访问时只需从内存中直接获取,那么显然可以带来显著的性能提升。引入缓存机制的难点是如何保证内存中数据的有效性,否则脏数据的出现将给系统带来难以预知的严重后果。虽然一个设计很好的应用程序不用缓存也可以表现出让人接受的性能,但毫无疑问,一些对读操作要求很高的应用程序可以通过缓存取得更高的性能。对于应用程序,缓存通过内存或磁盘保存了数据库的当前有关数据状态,它是一个存于当地的数据备份。缓存位于数据库和应用程序之间,从数据库更新数据,并给程序提供数据。

 

 Hibernate 的一级缓存是会话级缓存(Session-level),也就是常用到的Session,会话级缓存在给定的Session实例的生命周期内保存对象的实例。Session缓存类似于事务性缓存,只缓存给定的操作所需数据。二级缓存是应用级缓存(缓存服务).

 

 Hibernate支持四种缓存服务,EHCache(Easy Hibernate Cache)是默认服务。要使用其他的缓存服务(二级缓存)需要在hibernate.cfg.xml中配置。例:

Xml代码 复制代码
  1. <propertynamepropertyname="hibernate.cache.provider_class">  
  2.   
  3.    org.hibernate.cache.OSCacheProvider   
  4.   
  5. </property>  
   <propertyname="hibernate.cache.provider_class">

      org.hibernate.cache.OSCacheProvider

   </property>

 

 

 Hibernate提供的缓存支持

 

     EHCac

你可能感兴趣的:(Hibernate,bean,cache,网络应用,配置管理)