20160512--hibernate--缓存
缓存
缓存的作用主要用来提高性能,可以简单的理解成一个Map;使用缓存涉及到三个操作:把数据放入缓存、从缓存中获取数据、删除缓存中的无效数据。
原理模拟分析:(不能运行,只是模拟)(缓存实现复杂,hibernate运用了第三方框架实现)
package com.dzq.test; import java.util.*; import com.dzq.domain.User; public class CacheDemo { private static Map cache = new HashMap(); public static void main(String[] args) { } public User queryUser(int id) { String key = User.class.getName() + id; User user = (User) cache.get(key); if (user != null) { return user; } user = getFormDB(); cache.put(key, user); return user; } public User updateUser(User user) { String key = User.class.getName()+user.getId(); updateDB(user); cache.remove(key); return user; } private void updateDB(User user) { // TODO Auto-generated method stub } private User getFormDB() { // TODO Auto-generated method stub return null; } }
一级缓存,Session级共享。
save,update,saveOrUpdate,load,get,list,iterate,lock这些方法都会将对象放在一级缓存中,一级缓存不能控制缓存的数量,所以要注意大批量操作数据时可能造成内存溢出;可以用evict,clear方法清除缓存中的内容。
二级缓存,SessionFactory级共享。
①实现为可插拔,通过修改cache.provider_class参数来改变;
hibernate内置了对EhCache,OSCache,TreeCache,SwarmCache的支持,可以通过实现CacheProvider和Cache接口来加入Hibernate不支持的缓存实现。
②在hibernate.cfg.xml中加入:
<class-cache class="className" usage="read-only"/>
或在映射文件的class元素加入子元素:
<cache usage="read-write"/>
其中usage:read-only,read-write,nonstrict-read-write,transactional
③Session的:save(这个方法不适合native生成方式的主键),
update,saveOrUpdate,list,iterator,get,load,以及Query,Criteria都会填充二级缓存,但只有(没打开查询缓存时)Session的iterator,get,load会从二级缓存中取数据(iterator可能存在N+1次查询)。
④Query,Criteria(查询缓存)由于命中率较低,所以hibernate缺省是关闭;修改cache.use_query_cache为true打开对查询的缓存,并且调用query.setCacheable(true)或criteria.setCacheable(true)。
⑤SessionFactory中提供了evictXXX()方法用来清除缓存中的内容。
⑥统计信息打开generate_statistics,用sessionFactory.getSatistics()获取统计信息。
分布式缓存和中央缓存。
使用缓存的条件
1.读取大于修改。
2.数据量不能超过内存容量。
3.对数据要有独享的控制。
4.可以容忍出现无效数据。