hibernate二级缓存的使用需要进行必要的配置,主要是四个地方(这里以ehcache为例):
1>. 配置echcache.xml文件
2>.开启二级缓存,修改hibernate.cfg.xml文件
true
3>.指定缓存产品提供商,修改hibernate.cfg.xml文件
org.hibernate.cache.EhCacheProvider
4>.指定那些实体类使用二级缓存(两种方法)
1).在映射文件中采用标签
2).在hibernate.cfg.xml文件中,采用标签
hibernate二级缓存配置上之后,就成了“客观存在”,hibernate在使用某些方法的时候默认就使用和维护了二级缓存(哪怕你出于某种原因希望使用也不行)。因此,在使用二级缓存时进行一定的控制还是必要的,Session就提供了设置使用二级缓存的模式的方法 (setCacheMode)来实现,当session调用某个方法时对二级缓存的存取改变。
1.实体类:
|
Student.hbm.xml
<class name="com.sxt.hibernate.cache.entity.Student" table="sxt_hibernate_student"> <!-- 指定本类的对象使用二级缓存(这也可以放在hibernate.cfg.xml中统一指定) --> <!-- <cache usage="read-only"/> --> <id name="id" length="4"> <generator class="native"></generator> </id> <property name="name" length="10"></property> </class> |
3. 二级缓存配置文件:
ehcache.xml
maxElementsOnDisk:缓存在磁盘上的最大数目===可选项 memoryStoreEvictionPolicy:缓存算法,有LRU(默认)、LFU、FIFO=====可选项 |
hibernate.cfg.xml
<hibernate-configuration> <session-factory> <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:ORCL10</property> <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <property name="hibernate.connection.username">scott</property> <property name="hibernate.connection.password">yf123</property> <property name="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</property> <property name="hibernate.show_sql">true</property> <!-- 开启二级缓存,其实hibernate默认就是开启的,这里显示的指定一下 --> <property name="hibernate.cache.use_second_level_cache">true</property> <!-- 指定二级缓存产品的提供商 --> <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> <mapping resource="com/sxt/hibernate/cache/entity/Student.hbm.xml"/> <!-- 指定那些类使用二级缓存 --> <class-cache usage="read-only" class="com.sxt.hibernate.cache.entity.Student"/> </session-factory> </hibernate-configuration> |
=======================================================
4、StandardQueryCache
用于查询缓存使用,如果指定了该缓存,那么查询缓存将放在该缓存中。
- <cache
- name="org.hibernate.cache.StandardQueryCache"
- maxElementsInMemory="5"
- eternal="false"
- timeToLiveSeconds="120"
- overflowToDisk="true"/>
如果不给查询设置区域名默认缓存到这,可以通过“query.setCacheRegion("区域名");”来设置查询的区域名。
时间戳缓存,内部使用,用于保存最近更新的表的时间戳,这是非常重要的,无需失效,关闭时间戳缓存区域的过期时间。
- <cache
- name="org.hibernate.cache.UpdateTimestampsCache"
- maxElementsInMemory="5000"
- eternal="true"
- overflowToDisk="true"/>
Hibernate使用时间戳区域来决定被高速缓存的查询结果集是否是失效的。当你重新执行了一个启用了高速缓存的查询时,Hibernate就在时间戳缓存中查找对被查询的(几张)表所做的最近插入、更新或删除的时间戳。如果找到的时间戳晚于高速缓存查询结果的时间戳,那么缓存结果将被丢弃,重新执行一次查询。
8.4.6.2.11、什么时候需要查询缓存
大多数时候无法从结果集高速缓存获益。必须知道:每隔多久重复执行同一查询。
对于那些查询非常多但插入、删除、更新非常少的应用程序来说,查询缓存可提升性能。但写入多查询少的没有用,总失效。
8.4.6.2.12、管理一级缓存
无论何时,当你给save()、update()或 saveOrUpdate()方法传递一个对象时,或使用load()、 get()、list()、iterate() 或scroll()方法获得一个对象时, 该对象都将被加入到Session的内部缓存中。
当随后flush()方法被调用时,对象的状态会和数据库取得同步。 如果你不希望此同步操作发生,或者你正处理大量对象、需要对有效管理内存时,你可以调用evict() 方法,从一级缓存中去掉这些对象及其集合。
ScrollableResult cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set
while ( cats.next() ) {
Cat cat = (Cat) cats.get(0);
doSomethingWithACat(cat);
sess.evict(cat);
}
Session还提供了一个contains()方法,用来判断某个实例是否处于当前session的缓存中。
如若要把所有的对象从session缓存中彻底清除,则需要调用Session.clear()。
CacheMode参数用于控制具体的Session如何与二级缓存进行交互。
CacheMode.NORMAL - 从二级缓存中读、写数据。
CacheMode.GET - 从二级缓存中读取数据,仅在数据更新时对二级缓存写数据。
CacheMode.PUT - 仅向二级缓存写数据,但不从二级缓存中读数据。
CacheMode.REFRESH - 仅向二级缓存写数据,但不从二级缓存中读数据。通过 hibernate.cache.use_minimal_puts的设置,强制二级缓存从数据库中读取数据,刷新缓存内容。
8.4.6.2.12、管理二级缓存
对于二级缓存来说,在SessionFactory中定义了许多方法, 清除缓存中实例、整个类、集合实例或者整个集合。
sessionFactory.evict(Cat.class, catId); //evict a particular Cat
sessionFactory.evict(Cat.class); //evict all Cats
sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections
sessionFactory.evictQueries()//evict all queries
8.4.6.2.13、监控二级缓存
如若需要查看二级缓存或查询缓存区域的内容,你可以使用统计(Statistics) API。
通过sessionFactory.getStatistics();获取Hibernate统计信息。
此时,你必须手工打开统计选项。
hibernate.generate_statistics true
hibernate.cache.use_structured_entries true