2级缓存Cache及外部缓存Cache它能够越过数个Session通过同个SessionFactory进行管理和维护
接上例代码:http://blog.csdn.net/kunshan_shenbin/archive/2008/09/03/2874375.aspx
要使用 2级缓存Cache首先需要对hibernate.cfg.xml文件进行修改:
"-//Hibernate/HibernateConfigurationDTD3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
....
org.hibernate.cache.HashtableCacheProvider
....
HashtableCache是Hibernate自己所提供 2级缓存Cache实现但是由于其性能和功能有限般只用于开发和测试
当然我们可以使用第 3方实现譬如:org.hibernate.cache.EhCacheProvider这个需要ehcathe.jar包
修改User.hbm.xml文件:
PUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
="com.hb3.pack_21.model.Room"
cascade="save-update"
outer-join="true"/>
>
这里追加策略有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文件内容为:
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
测试代码如下:
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
.out.prln(user.getName);
}
query=session.createQuery(hql);
users=query.list;
for(i=0;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属性:
"-//Hibernate/HibernateConfigurationDTD3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
....
....
然后在每次简历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
.out.prln(user.getName);
}
query=session.createQuery(hql);
//使用Query快取
query.Cacheable(true);
users=query.list;
for(i=0;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