hibernate二级缓存:hibernate3学习笔记( 2十一)| 2级缓存Cache
2009-09-06 02:20
225 查看
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
接上例代码: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
相关文章推荐
- hibernate二级缓存:hibernate3 2级缓存Cache的配置及测试
- spring+hibernate+Jboss treeCache配置二级缓存(一)
- hibernate_二级缓存(second cache)
- 在hibernate中使用二级缓存的时候指定CacheConcurrencyStrategy.READ_WRITE修改后接着用for-each 或 iterator访问时报错ConcurrentMod
- hibernate中cache二级缓存问题
- Hibernate二级缓存详解
- 【Hibernate】hibernate的二级缓存(spring)
- 主题:hibernate二级缓存攻略
- Hibernate 二级缓存
- hibernate + ehcache 二级缓存技术
- Hibernate--二级缓存
- hibernate的二级缓存的配置使用
- spring mybatis mvc cache 缓存 二级缓存
- hibernate 二级缓存
- Hibernate中的一级缓存、二级缓存和懒加载
- hibernate一级缓存,二级缓存,三级缓存,缓存算法及配置。
- Hibernate中 一 二级缓存及查询缓存
- 关于hibernate的二级缓存学习
- hibernate二级缓存策略
- Hibernate-----17、二级缓存和查询缓存