zoukankan      html  css  js  c++  java
  • Hibernate 的Ehache学习

    Hibernate默认二级缓存是不启动的,启动二级缓存(以EHCache为例)需要以下步骤:

    1、添加相关的包:

    Ehcache.jar和commons-logging.jar,如果hibernate.jar中含有ehcache就不用添加Ehcache.jar,commons-logging.jar是用来实现Ehcache写日志的。本示例使用Hibernate3.2

    2、配置hibernate.cfg.xml文件

    1. <hibernate-configuration>  
    2.     <session-factory>  
    3.       <property name="hibernate.show_sql">true</property>  
    4.       <property name="hibernate.cache.provider_class"> net.sf.ehcache.hibernate.EhCacheProvider</property><!-- 指定cache实现类 -->  
    5.      <property name="cache.use_second_level_cache">true</property><!-- 启用二级缓存 -->  
    6.      <property name="hibernate.cache.use_query_cache">true</property><!-- 启用查询缓存 -->  
    7.  <!-- <property name="hibernate.cache.provider_configuration_file_resource_path">ehcache2.xml</property>//指定ehcache配置文件 -->  
    8.   
    9.      <mapping class="test.po.TUser" />  
    10.   
    11.     </session-factory>  
    12. </hibernate-configuration>  

    3、添加配置文件--ehcache.xml,一般放在classpath或src下,也可以自定义文件名和路径,并在hibernate.cfg.xml中通过 hibernate.cache.provider_configuration_file_resource_path参数指定。

    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <ehcache>  
    3. <defaultCache maxElementsInMemory="10000"   
    4.         eternal="false"   
    5.         timeToIdleSeconds="1000"   
    6.         timeToLiveSeconds="1000"  
    7.         overflowToDisk="false"   
    8.         memoryStoreEvictionPolicy="LRU"/>  
    9. </ehcache>  

    其中:

    maxElementsInMemory=“10000” //Cache中最多允许保存的数据对象的数量
    external=“false” //缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期 
    timeToIdleSeconds=“1000”  //缓存数据钝化时间(设置对象在它过期之前的空闲时间)  
    timeToLiveSeconds=“1000”  //缓存数据的生存时间(设置对象在它过期之前的生存时间)

    overflowToDisk=“false” />    //内存不足时,是否启用磁盘缓存  

    memoryStoreEvictionPolicy="LRU" //内存不足时数据对象的清除策略

    ehcache中缓存的3种清空策略:
     FIFO(first in first out):先进先出

     LFU( Less Frequently Used):一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
     LRU(Least Recently Used):最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。

    4、配置相关实体的缓存策略

    1. @Entity  
    2. @Table(name="cui_user")  
    3. @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)//可读可写   
    4. public class TUser {  
    5. private Integer id;  
    6. private String name;  
    7.   
    8. @Id //标识主键   
    9. @GeneratedValue(strategy=GenerationType.AUTO)//指定主键值的产生策略由Hibernate根据数据库字段选择   
    10. public Integer getId() {  
    11.     return id;  
    12. }  
    13. public void setId(Integer id) {  
    14.     this.id = id;  
    15. }  
    16. public String getName() {  
    17.     return name;  
    18. }  
    19. public void setName(String name) {  
    20.     this.name = name;  
    21. }  
    22. }  

    最后还是需要测试的。通过id缓存的例子如下:

    1. public static void main(String[] args) {  
    2.         //单对象缓存   
    3.         Session session=HibernateSessionFactory.getSession();  
    4.     TUser user=(TUser)session.load(TUser.class, 200);  
    5.     System.out.println("1---"+user.getName());  
    6.     session.close();  
    7.           
    8.     try {  
    9.         Thread.sleep(2000);//休眠2秒   
    10.     } catch (InterruptedException e) {  
    11.         e.printStackTrace();  
    12.     }  
    13.           
    14.     session=HibernateSessionFactory.getSession();  
    15.     TUser user2=(TUser)session.load(TUser.class, 200);  
    16.     System.out.println("2---"+user2.getName());  
    17.     session.close();          
    18. }  

    Hibernate生成的sql语句:

    Hibernate: select tuser0_.id as id0_0_, tuser0_.name as name0_0_ from cui_user tuser0_ where tuser0_.id=?
    1---cuisea
    2---cuisea

    可见第二次读取TUser对象并没有去数据库查询,说明是从缓存里读取的,ehcache配置成功。

    查询缓存(必须在hibernate.cfg.xml中配置hibernate.cache.use_query_cache为true)的例子如下:

    1. public static void main(String[] args) {  
    2.     Session session=HibernateSessionFactory.getSession();  
    3.     Query query=session.createQuery("from TUser");//使用Query缓存结果集   
    4.     query.setCacheable(true);//必须设置   
    5.     List<TUser> list=query.list();  
    6.     for (TUser user : list) {  
    7.         System.out.println("1---"+user.getName());  
    8.     }  
    9.       
    10.         //另外开启一个事务     
    11.     session=HibernateSessionFactory.getSession();  
    12.     query=session.createQuery("from TUser");  
    13.     query.setCacheable(true);//必须设置   
    14.     list=query.list();  
    15.     for (TUser user : list) {  
    16.         System.out.println("2---"+user.getName());  
    17.     }  
    18. }  

    Hibernate生成的sql语句:

    Hibernate: select tuser0_.id as id0_, tuser0_.name as name0_ from cui_user tuser0_
    1---tester
    1---cuisea
    2---tester
    2---cuisea

    可见,第二次查询并没有从数据库查询,而是从缓存中取数据。查询缓存使用hibernate生成的sql语句和参数作为key缓存起来,当执行相同的sql并使用相同参数时从缓存取数据。

  • 相关阅读:
    PAT B1027 打印沙漏 (20 分)
    PAT B1025 反转链表 (25 分)
    PAT B1022 D进制的A+B (20 分)
    PAT B1018 锤子剪刀布 (20 分)
    PAT B1017 A除以B (20 分)
    PAT B1015 德才论 (25 分)
    PAT B1013 数素数 (20 分)
    PAT B1010 一元多项式求导 (25 分)
    HDU 1405 The Last Practice
    HDU 1165 Eddy's research II
  • 原文地址:https://www.cnblogs.com/zengda/p/4464851.html
Copyright © 2011-2022 走看看