hibernate二级缓存:hibernate3学习笔记( 2十一)| 2级缓存Cache

来源:互联网 发布:google play软件下载 编辑:程序博客网 时间:2024/05/21 17:59

2级缓存Cache及外部缓存Cache它能够越过数个Session通过同个SessionFactory进行管理和维护

  接上例代码:http://blog.csdn.net/kunshan_shenbin/archive/2008/09/03/2874375.aspx

  要使用 2级缓存Cache首先需要对hibernate.cfg.xml文件进行修改:

<?xmlversion="1.0"encoding="utf-8"?> 
<!DOCTYPEhibernate-configurationPUBLIC
  "-//Hibernate/HibernateConfigurationDTD3.0//EN"
  "
http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration> 
  <session-factory> 
    ....
    <propertyname="hibernate.cache.provider_">
      org.hibernate.cache.HashtableCacheProvider
    </property>
    ....
  </session-factory> 
</hibernate-configuration>

  HashtableCache是Hibernate自己所提供 2级缓存Cache实现但是由于其性能和功能有限般只用于开发和测试

  当然我们可以使用第 3方实现譬如:org.hibernate.cache.EhCacheProvider这个需要ehcathe.jar包

  修改User.hbm.xml文件:

<?xmlversion="1.0"encoding="utf-8"?>
<!DOCTYPEhibernate-mapping 
  PUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN" 
  "
http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping> 
  <name="com.hb3.pack_21.model.User"table="user">
    <cacheusage="read-write"/>
    <idname="id"column="id"type="java.lang.Integer"> 
      <generator="native"/> 
    </id> 
    <propertyname="name"column="name"type="java.lang.String"/> 
    <many-to-onename="room" 
          column="room_id" 
          ="com.hb3.pack_21.model.Room"
          cascade="save-update"
          outer-join="true"/> 
  </> 
</hibernate-mapping>

  这里追加策略有read-only、read-write、nonstrict-read-write以及transactional区别第 3方缓存Cache实现所支持种类是区别请参阅:http://www.hibernate.org/hib_docs/v3/reference/en/html/performance.html#performance-cache

  在工程path下追加ehcache.xml文件内容为:

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

  测试代码如下:

packagecom.hb3.pack_21;
importjava.io.IOException;
importjava.sql.SQLException;
importorg.hibernate.Session;
importorg.hibernate.SessionFactory;
importorg.hibernate.cfg.Configuration;
importcom.hb3.pack_21.model.User;
publicBusinessService{
  publicvoid(Stringargs)throwsIOException,SQLException{
    Configurationconfig=Configuration.configure;
    SessionFactorysessionFactory=config.buildSessionFactory;   
    Sessionsession=sessionFactory.openSession;
    Useruser1=(User)session.load(User.,Integer(1));
    user1.getName;
    session.close;
    session=sessionFactory.openSession;
    Useruser2=(User)session.load(User.,Integer(1));
    user2.getName;
    session.close;
    sessionFactory.close;
  }
}

 

  如果不使用 2级缓存Cache机制生成SQL文为:

Hibernate:
select user0_.id as id0_, user0_.name as name0_0_, user0_.age as age0_0_
from user user0_ where user0_.id=?
Hibernate:
select user0_.id as id0_, user0_.name as name0_0_, user0_.age as age0_0_
from user user0_ where user0_.id=?

  使用后第 2级做相同查询会从 2级缓存Cache中读取

  当然如果打算从 2级缓存Cache中清空对象缓存Cache信息可以使用SessionFactoryevict思路方法如:

  sessionFactory.evict(User., user.getId);

测试代码如下:

packagecom.hb3.pack_22;
importjava.io.IOException;
importjava.sql.SQLException;
importjava.util.List;
importorg.hibernate.Query;
importorg.hibernate.Session;
importorg.hibernate.SessionFactory;
importorg.hibernate.cfg.Configuration;
importcom.hb3.pack_22.model.User;
publicBusinessService{
  publicvoid(Stringargs)throwsIOException,SQLException{
    Configurationconfig=Configuration.configure;
    SessionFactorysessionFactory=config.buildSessionFactory;   
    Sessionsession=sessionFactory.openSession;
    Stringhql="fromcom.hb3.pack_22.model.User";
    Queryquery=session.createQuery(hql);
    List<?>users=query.list;
    for(i=0;i<users.size;i){
      Useruser=(User)users.get(i);
      .out.prln(user.getName);
    }
    query=session.createQuery(hql);
    users=query.list;
    for(i=0;i<users.size;i){
      Useruser=(User)users.get(i);
      .out.prln(user.getName);
    }
    session.close;
    sessionFactory.close;
  }
}

  执行结果为:

Hibernate: select user0_.id as id0_, user0_.name as name0_, user0_.room_id as room3_0_ from user user0_
chenyan
shenbin
Hibernate: select user0_.id as id0_, user0_.name as name0_, user0_.room_id as room3_0_ from user user0_
chenyan
shenbin

  可见没有启用Query快取功能

  如果打算打开Query快取功能首先在hibernate.cfg.xml中设定hibernate.cache.use_query_cache属性:

<?xmlversion="1.0"encoding="utf-8"?> 
<!DOCTYPEhibernate-configurationPUBLIC
  "-//Hibernate/HibernateConfigurationDTD3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration> 
  <session-factory> 
    .... 
    <propertyname="hibernate.cache.use_query_cache">true</property> 
    ....
  </session-factory> 
</hibernate-configuration>

  然后在每次简历Query时执行Cacheable(true):

packagecom.hb3.pack_22;
importjava.io.IOException;
importjava.sql.SQLException;
importjava.util.List;
importorg.hibernate.Query;
importorg.hibernate.Session;
importorg.hibernate.SessionFactory;
importorg.hibernate.cfg.Configuration;
importcom.hb3.pack_22.model.User;
publicBusinessService{
  publicvoid(Stringargs)throwsIOException,SQLException{
    Configurationconfig=Configuration.configure;
    SessionFactorysessionFactory=config.buildSessionFactory;   
    Sessionsession=sessionFactory.openSession;
    Stringhql="fromcom.hb3.pack_22.model.User";
    Queryquery=session.createQuery(hql);
    //使用Query快取
    query.Cacheable(true);
    List<?>users=query.list;
    for(i=0;i<users.size;i){
      Useruser=(User)users.get(i);
      .out.prln(user.getName);
    }
    query=session.createQuery(hql);
    //使用Query快取
    query.Cacheable(true);
    users=query.list;
    for(i=0;i<users.size;i){
      Useruser=(User)users.get(i);
      .out.prln(user.getName);
    }
    session.close;
    sessionFactory.close;
  }
}

  执行结果为:

Hibernate: select user0_.id as id0_, user0_.name as name0_, user0_.room_id as room3_0_ from user user0_
chenyan
shenbin
chenyan
shenbin

  其实Hibernate在启用Query缓存Cache机制后会保留执行过查询SQL和查询结果在下次查询后会看看SQL是否相同并看看对应资料库表格是否有变动(Update/Delete/Insert),如果SQL相同且且资料库也没有变动则将缓存Cache中结果直接返回

  值得提是Query上有list和iterator2个思路方法用于结果集返回他们区别是list思路方法在读取数据库时不会使用缓存Cache机制而直接向数据库发起查询而iterator则会将读取到结果写到缓存Cache中以便于读取时再次利用

Sessionsession=sessionFactory.openSession;
Queryquery=session.createQuery("fromUser");
Listusers=query.list;
users=query.list;
session.close;

  执行结果:

Hibernate: select user0_.id as id, user0_.name as name0_, user0_.age as age0_ from user user0_
Hibernate: select user0_.id as id, user0_.name as name0_, user0_.age as age0_ from user user0_
Sessionsession=sessionFactory.openSession;
Queryquery=session.createQuery("fromUser");
Iteratorusers=query.iterate;
users=query.iterate;
session.close;

  执行结果:

Hibernate: select user0_.id as col_0_0_ from user user0_
Hibernate: select user0_.id as col_0_0_ from user user0_

  由于使用iterator思路方法时会使用到Session level缓存Cache所以在查询大量记录时会好用大量记忆体必要时可以使用Sessionevict或clear思路方法来清除缓存Cache

  请参阅:http://blogger.org.cn/blog/more.asp?name=NaddyLee&id=31540

  请注意尽管iterator思路方法时会使用到Session level缓存Cache,但这不能就说在任何情况下都是最有效率做法

  请看下面测试:

packagecom.hb3.pack_22;
importjava.io.IOException;
importjava.sql.SQLException;
importjava.util.Iterator;
importjava.util.List;
importorg.hibernate.Query;
importorg.hibernate.Session;
importorg.hibernate.SessionFactory;
importorg.hibernate.cfg.Configuration;
importcom.hb3.pack_22.model.User;
publicBusinessService{
  publicvoid(Stringargs)throwsIOException,SQLException{
    Configurationconfig=Configuration.configure;
    SessionFactorysessionFactory=config.buildSessionFactory;   
    Sessionsession=sessionFactory.openSession;
    Stringhql="fromcom.hb3.pack_22.model.User";
    Queryquery=session.createQuery(hql);
//    List<?>list=query.list;
//    Iterator<?>iterator=list.iterator;
//    while(iterator.hasNext){
//     Useruser=(User)iterator.next;
//     .out.prln(user.getRoom.getAddress);
//   }
//    .out.prln("=");
//    list=query.list;
//    iterator=list.iterator;
//    while(iterator.hasNext){
//     Useruser=(User)iterator.next;
//     .out.prln(user.getRoom.getAddress);
//   }
//    
//    .out.prln("");
    query=session.createQuery(hql);
    Iterator<?>iterator=query.iterate;
    while(iterator.hasNext){
      Useruser=(User)iterator.next;
      .out.prln(user.getName);
    }
    .out.prln("=");
    iterator=query.iterate;
    while(iterator.hasNext){
      Useruser=(User)iterator.next;
      .out.prln(user.getName);
    }
    session.close;
    sessionFactory.close;
  }
}

  执行结果:

Hibernate: select user0_.id as col_0_0_ from user user0_
Hibernate: select user0_.id as id0_1_, user0_.name as name0_1_, user0_.room_id as room3_0_1_, room1_.id as id1_0_, room1_.address as address1_0_ from user user0_ left outer join room room1_ _disibledevent=
Hibernate: select user0_.id as col_0_0_ from user user0_
chenyan
shenbin

  这明显在性能上要优于刚才做法可见首次查询使用query.list性能要优于query.iterate的后再做相同查询请求时则借助缓存Cache机制使用query.iterate会大大提高性能

 

http://www.crazycoder.cn/Java/Article53736.html

 

原创粉丝点击