一级缓存与二级缓存
a.一级缓存(session级的缓存):在一个session中load同一个对象2次,load时,hibernate首先在session缓存中查找对象,如果没找到就到数据库中去load。因此,在同一个session中load一个对象2次,只会发出一条sql语句。
b.二级缓存即sessionfactory级别的缓存,hibernate支持多种二级缓存,常用ehcache
-------------------------------------------------------------------------------------------------------------------------
二级缓存的应用步骤:
1.在hibernate.cfg.xml中加上:
<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<property name="cache.use_query_cache">true</property>在applicationContext.xml中的Hibernate SessionFactory配置:
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.OracleDialect
</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.use_second_level_cache">true</prop><prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<!--
<prop key="hibernate.hbm2ddl.auto">update</prop>
-->
</props>
</property>2.把hibernate包里的ehcache.xml文件放到src目录下
<ehcache> <!-- Sets the path to the directory where cache .data files are created. If the path is a Java System Property it is replaced by its value in the running VM. The following properties are translated: user.home - User's home directory user.dir - User's current working directory java.io.tmpdir - Default temp file path --> <diskStore path="java.io.tmpdir"/> <!--Default Cache configuration. These will applied to caches programmatically created through the CacheManager. The following attributes are required for defaultCache: maxInMemory - Sets the maximum number of objects that will be created in memory eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used if the element is not eternal. Idle time is now - last accessed time timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used if the element is not eternal. TTL is now - creation time overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache has reached the maxInMemory limit. --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="1200" overflowToDisk="true" /> <!--Predefined caches. Add your cache configuration settings here. If you do not have a configuration for your cache a WARNING will be issued when the CacheManager starts The following attributes are required for defaultCache: name - Sets the name of the cache. This is used to identify the cache. It must be unique. maxInMemory - Sets the maximum number of objects that will be created in memory eternal - Sets whether elements are eternal. If eternal, timeouts are ignored and the element is never expired. timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used if the element is not eternal. Idle time is now - last accessed time timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used if the element is not eternal. TTL is now - creation time overflowToDisk - Sets whether elements can overflow to disk when the in-memory cache has reached the maxInMemory limit. --> <!-- Sample cache named sampleCache1 This cache contains a maximum in memory of 10000 elements, and will expire an element if it is idle for more than 5 minutes and lives for more than 10 minutes. If there are more than 10000 elements it will overflow to the disk cache, which in this configuration will go to wherever java.io.tmp is defined on your system. On a standard Linux system this will be /tmp" --> <cache name="sampleCache1" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true" /> <!-- Sample cache named sampleCache2 This cache contains 1000 elements. Elements will always be held in memory. They are not expired. --> <cache name="sampleCache2" maxElementsInMemory="1000" eternal="true" timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="false" /> --> <!-- Place configuration for your caches following --> </ehcache>
i.必须要有的属性:
name: cache的名字,用来识别不同的cache,必须惟一。
maxElementsInMemory: 内存管理的缓存元素数量最大限值。
maxElementsOnDisk: 硬盘管理的缓存元素数量最大限值。默认值为0,就是没有限制。
eternal: 设定元素是否持久话。若设为true,则缓存元素不会过期。
overflowToDisk: 设定是否在内存填满的时候把数据转到磁盘上。
ii.下面是一些可选属性:
timeToIdleSeconds:设定元素在过期前空闲状态的时间,只对非持久性缓存对象有效。默认值为0,值为0意味着元素可以闲置至无限长时间。
timeToLiveSeconds: 设定元素从创建到过期的时间。其他与timeToIdleSeconds类似。
diskPersistent: 设定在虚拟机重启时是否进行磁盘存储,默认为false.(我的直觉,对于安全小型应用,宜设为true)。
diskExpiryThreadIntervalSeconds: 访问磁盘线程活动时间。
diskSpoolBufferSizeMB: 存入磁盘时的缓冲区大小,默认30MB,每个缓存都有自己的缓冲区。
memoryStoreEvictionPolicy: 元素逐出缓存规则。共有三种,Recently Used (LRU)最近最少使用,为默认。 First In First Out (FIFO),先进先出。Less Frequently Used(specified as LFU)最少使用。
上面的ehcache.xml文件除了 defaultCache缓存外,还有sampleCache1和sampleCache2,在给实体设置缓存的时候可以指定缓存
3.@ecache注解,如下例子:@Entity @Cache(usage = CacheConcurrencyStrategy.READ_WRITE) public class Permission{ private int id; private String name; @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }4.加入ehcache-1.5.0.jar包,在hibernate-distribution-3.6.0.Final\lib\optional\ehcache目录下注意:ehcache使用了commons-logging的包,也要加上
二级缓存总结:
----------------------------------------------------------------------------------------------------a.load和iterator默认使用二级缓存
b.list默认往二级缓存加数据,但是查询的时候不使用
查询缓存:
如果要query用二级缓存,需打开查询缓存:
<property name="hibernate.cache.use_query_cache">true</property>
注意:a.查询缓存依赖于二级缓存,必须打开二级缓存
b.查询缓存在查询条件一样的时候才会起作用,如果条件不一样则不起作用
c.调用Query的setCachable(true)方法指明使用二级缓存
源码eg:
Session session = sf.openSession(); session.beginTransaction(); List<Category> categories = (List<Category>)session.createQuery("from Category") .setCacheable(true).list(); session.getTransaction().commit(); session.close(); Session session2 = sf.openSession(); session2.beginTransaction(); List<Category> categories2 = (List<Category>)session2.createQuery("from Category") .setCacheable(true).list(); session2.getTransaction().commit(); session2.close();
缓存算法:
1.LRU:least Recently Used 最近最少用到的
2.LFU:least Frequently Used(命中率高低)
3.FIFO:First In First Out 类似数组,先进先出
ehcache对这三种算法都支持,我们可以在ehcache.xml中增加:
<defaultCache maxElementsInMemory="10000" <!--缓存存储的最大数量 --> eternal="false" <!-- 设定元素是否持久话。若设为true,则缓存元素不会过期 --> timeToIdleSeconds="120" <!-- 设定元素在过期前空闲状态的时间,只对非持久性缓存对象有效。默认值为0,值为0意味着元素可以闲置至无限长时间 --> timeToLiveSeconds="1200" <!-- 设定元素从创建到过期的时间,其他与timeToIdleSeconds类似 --> overflowToDisk="true" <!-- 设定是否在内存填满的时候把数据转到磁盘上 --> memoryStoreEvictionPolicy=“LRU”
/>好文章: http://blog.csdn.net/nuoyan666/article/details/6577732
http://www.ibm.com/developerworks/cn/java/j-lo-ehcache/index.html(集群,有时间在看)
http://hi.baidu.com/yinaddress/blog/item/f333f0d9af38f93e33fa1c28.html
http://hi.baidu.com/liang125353769/blog/item/a5ec79eb571b44cbd439c92d.html