Hibernate二级缓存
1) 条件查询的时候,总是发出一条select * from table_name where …. (选择所有字段)这样的SQL语句查询数据库,一次获得所有的数据对象。
2) 把获得的所有数据对象根据ID放入到第二级缓存中。
3) 当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;查不到,如果配置了二级缓存,那么从二级缓存中查;查不到,再查询数据库,把结果按照ID放入到缓存。
4) 删除、更新、增加数据的时候,同时更新缓存。
Hibernate二级缓存策略,是针对于ID查询的缓存策略,对于条件查询则毫无作用。为此,Hibernate提供了针对条件查询的Query Cache。
1) 很少被修改的数据
2) 不是很重要的数据,允许出现偶尔并发的数据
3) 不会被并发访问的数据
4) 参考数据,指的是供应用参考的常量数据,它的实例数目有限,它的实例会被许多其他类的实例引用,实例极少或者从来不会被修改。
1) 经常被修改的数据
2) 财务数据,绝对不允许出现并发
3) 与其他应用共享的数据。
◆EhCache:可作为进程范围的缓存,存放数据的物理介质可以是内存或硬盘,对Hibernate的查询缓存提供了支持。
◆OSCache:可作为进程范围的缓存,存放数据的物理介质可以是内存或硬盘,提供了丰富的缓存数据过期策略,对Hibernate的查询缓存提供了支持。
◆SwarmCache:可作为群集范围内的缓存,但不支持Hibernate的查询缓存。
◆JBossCache:可作为群集范围内的缓存,支持事务型并发访问策略,对Hibernate的查询缓存提供了支持。
1) 选择需要使用二级缓存的持久化类,设置它的命名缓存的并发访问策略。这是最值得认真考虑的步骤。
2) 选择合适的缓存插件,然后编辑该插件的配置文件。
对于经常使用的查询语句,如果启用了查询缓存,当第一次执行查询语句时,hibernate会把查询结果存放在第二级缓存中,以后再次执行该查询语句时,只需从缓存中获得查询结果,从而提高查询性能。如果查询结果中包含实体,第二级缓存只会存放实体的OID,而对于投影查询,第二级缓存会存放所有的数据值。
查询缓存适用于以下场合:在应用程序运行时经常使用的查询语句;很少对与查询语句关联的数据库数据进行插入,删除,更新操作。
对查询语句启用查询缓存的步骤如下:
1,配置第二级缓存。
2,在hibernate的配置文件中设置查询缓存属性:hibernate.cache.use_query_cache=true
3,即使设置了缓存,在执行查询语句时仍然不会启用查询缓存,只有在调用query.setCacheable()后才启用缓存:
Query query = session.createQuery("from Customer c where c.age > :age");
query.setInteger("age", age):
query.setCacheable(true);
如果希望更加精粒度地控制查询缓存,可以设置缓存区域:query.setCacheRegion("customerQueries");
hibernate提供了3种和查询相关的缓存区域:
1,默认的查询缓存区域:net.sf.hibernate.cache.StandardQueryCache。
2,用户自定义的查询缓存区域:如customerQueries。
3,时间戳缓存区域:net.sf.hibernate.cache.UpdateTimestampCache。
默认的查询缓存区域以及用户自定义的查询缓存区域都用于存放查询结果,而时间戳缓存区域存放了对于查询结果相关的表进行插入,更新,删除操作的时间戳。 hibernate通过时间戳缓存区域来判断被缓存的查询结果是否过期。当应用进程对数据库的相关数据做了修改,hibernate会自动刷新缓存的查询结果。但是如果其它应用进程对数据库的相关数据做了修改,hibernate无法监测到这一变化,此时必须由应用程序负责监测这一变化(如通过发送和接收事件或消息机制),然后手工刷新查询结果。
Query.setForceCacheRefresh(true)方法允许手工刷新查询结果,它使得hibernate丢弃查询缓存区域中己有的查询结果,重新到数据库中查询数据,再把查询结果存放在查询缓存区域中。
下面是比较hibernate的一级缓存和二级缓存

不要想当然的以为缓存一定能提高性能,仅仅在你能够驾驭它并且条件合适的情况下才是这样的。hibernate的二级缓存限制还是比较多的,不方便用jdbc可能会大大的降低更新性能。在不了解原理的情况下乱用,可能会有1+N的问题。不当的使用还可能导致读出脏数据。
如果受不了hibernate的诸多限制,那么还是自己在应用程序的层面上做缓存吧。
在越高的层面上做缓存,效果就会越好。就好像尽管磁盘有缓存,数据库还是要实现自己的缓存,尽管数据库有缓存,咱们的应用程序还是要做缓存。因为底层的缓存它并不知道高层要用这些数据干什么,只能做的比较通用,而高层可以有针对性的实现缓存,所以在更高的级别上做缓存,效果也要好些吧。

浙公网安备 33010602011771号