JAVA缓存最简单一种实现
创建一个静态的map ConcurrentHashMap 线程安全
本地文件缓存
Ehcache 缓存
jar包
ehcache-core-2.5.2.jar slf4j-api-1.6.1.jar slf4j-jdk14-1.6.1.jar
配置 ehcache.xml
可配置多个cache
通过 Cache sample = cacheManager.getCache("name");获取缓存对象
xsi:noNamespaceSchemaLocation="../bin/ehcache.xsd">
JAVA 代码
1.获取CacheManager 对象 不传参数表示默认路径 可以传入文件路径和网络地址
2.CacheManager cacheManager = CacheManager.create();
获取ehcache.xml 文件里配置好的 cache
Cache sample = cacheManager.getCache("SimplePageCachingFilter");
3.创建 缓存元素 key 和 val 字面意思
Element element = new Element("key", "val");
4.sample.put(element); 将缓存对象 加入缓存
通过key获取cache中的 缓存元素
Element result = sample.get("key");
注意添加到cache中对象要序列化 实现Serializable接口
通过 次元素 可获取 val等 属性的值
删除缓存
sample.remove("key");
sample.removeAll();
获取所有的缓存对象
for (Object key : cache.getKeys()) {
System.out.println(key);
}
得到缓存中的对象数
cache.getSize();
得到缓存对象占用内存的大小
cache.getMemoryStoreSize();
得到缓存读取的命中次数
cache.getStatistics().getCacheHits();
得到缓存读取的错失次数
cache.getStatistics().getCacheMisses();
写入磁盘
cache.flush();
要想把cache真正持久化到磁盘,写程序时必须注意,在是用net.sf.ehcache.Cache的void put (Element element)方法后要使用void flush()方法
创建个缓存
Ehcache cache = new Cache("testCache", 5000, false, false, 5, 2);
sample.add(cache )
Ehcache整合MyBatis
导入 mybatis-ehcache-1.0.0.jar 还有其他myBatis相关包
mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
select * from person where id=#{id}
通过注释的方式 整合
@CacheNamespace(implementation=org.mybatis.caches.ehcache.EhcacheCache.class)
EhcacheCache 实现了 mybatis的 Cache接口
默认获取根目录下的ehcache.xml文件
如果 之前在ehcache.xml 没有配置过 相应的cache
这里会根据 id创建一个cache
id= Dao的地址
在ehcache.xml配置 cache麻烦的话
可以 自定义类 继承EhcacheCache 重写 获取cache 将@CacheNamespace
注解里面的参数传进去 自定义 cache
Ehcache页面缓存
jar包
net.sf.ehcache
ehcache-web
2.0.4
页面缓存主要用Filter过滤器对请求的url进行过滤,如果该url在缓存中出现。那么页面数据就从缓存对象中获取,并以gzip压缩后返回。其速度是没有压缩缓存时速度的3-5倍,效率相当之高!其中页面缓存的过滤器有CachingFilter,一般要扩展filter或是自定义Filter都继承该CachingFilter
自定义类 继承 SimplePageCachingFilter
重写 doFilter方法 在里面先判断 是否是要缓存的地址
如果是就调用super.doFilter(request, response, chain);
如果不是就调用chain.doFilter(request, response);
SimplePageCachingFilter里面默认获取 名字SimplePageCachingFilter的cache配置
重写getCacheName方法 设置cache名字
默认key :
stringBuffer.append(httpRequest.getMethod()).append(httpRequest.getRequestURI()).append(httpRequest.getQueryString())
可以重写 SimplePageCachingFilter的calculateKey()方法 自己定义key
Ehcache Spring 整合
在类或方法上@Cacheable
@Cacheable(value=”cache”)
这个注释的意思是,当调用这个方法的时候,会从一个名叫 cache的缓存中查询,如果没有,则执行实际的方法(即查询数据库),并将执行的结果存入缓存中,否则返回缓存中的对象。
同时 还有@CacheEvict @CachePut等注解
详解
远程缓存
Memcached
java memcached client
jar包
commons-pool-1.5.6.jar
java_memcached-release_2.6.6.jar
slf4j-api-1.6.1.jar
slf4j-simple-1.6.1.jar
主要是两个类
SockIOPool 和MemCachedClient
SockIOPool 这个类用来创建管理客户端和服务器通讯连接池
MemCachedClient 缓存的管理
set方法gei方法 等
memcached 缓存对象 需要 实现序列化
set方法gei方法 等
注:设置有效时间为5秒是
new Date(5000) 不是new Date(System.currentTimeMillis()+5000)神逻辑
更多API
java memcached client 整合spring
factory-method="getInstance" init-method="initialize" destroy-method="shutDown">
neeaMemcachedPool
127.1.0.1:11211
10
250
30
false
3000
neeaMemcachedPool
参考
Ehcache
整合
Spring
org.springframework.cache.ehcache.EhCacheCacheManager 重org.springframework.cache.Cache和org.springframework.cache.support.AbstractCacheManager
mybatis和memcached的整合
mybatis和memcached的整合
JAR 包
org.mybatis.caches
mybatis-memcached
1.0.0
打印日志
...
memcache的配置是根据classpath下的 /memcached.properties 配置的,如果没有使用默
还可以实现 mybatis的 Cache接口 进行整合
使用Simple-Spring-Memcached注解做缓存操作
针对xmemcached 客户端
com.google.code.simple-spring-memcached
xmemcached-provider
3.6.0
com.google.code.simple-spring-memcached
spymemcached-provider
3.6.0
Spring 配置
http://https://code.google.com/p/simple-spring-memcached/wiki/Getting_Started#@CacheKeyMethod
这里面有针对不同客户端的spring配置
simplesm-context.xml 在simple-spring-memcached-3.4.0.jar 包里
在方法上 使用 @ReadThroughSingleCache
两个参数 namespace key前缀 expiration到期时间
在参数上@ParameterValueKeyProvider 生成key 多个参数时候 需要指定 order 值
注 参数不能带空格 或者空的 会报错
@InvalidateSingleCache
作用:失效Cache中的数据
@UpdateSingleCache
作用:更新Cache中的数据 等等
@CacheKeyMethod 标记做为参数 的对象方法上 调用该方法生产key 不包含此注解则调用 toString方法
xmemcached 客户端
Jar 包
com.googlecode.xmemcached
xmemcached
2.0.0
MemcachedClientBuilder builder = new XMemcachedClientBuilder(
AddrUtil.getAddresses("127.1.0.1:11211"), new int[] { 1, 1, 1, 1 }
//设置连接池大小,即客户端个数
builder.setConnectionPoolSize(50);
//宕机报警
builder.setFailureMode(true);
//使用二进制文件
builder.setCommandFactory(new BinaryCommandFactory());
MemcachedClient memcachedClient = null;
try {
memcachedClient = builder.build();
try {
memcachedClient.set("zlex", 36000, "set/get");
memcachedClient.get("zlex",);
} catch (TimeoutException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (MemcachedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();}
API
http://www.tuicool.com/articles/qMnQVfe
Redis
redis.clients
jedis
2.0.0
Jedis客户端
连接池配置
//连接池配置
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(10);
config.setMaxIdle(50);//设置最大空闲数
config.setBlockWhenExhausted(false);
config.setMaxWaitMillis(timeout);//设置超时时间
config.setMinEvictableIdleTimeMillis(30000);
更多参数 详解
//获得连接池
JedisPool pool == new JedisPool(config, host, port, timeout)
//jedisPool对象 可以通过spring 进行封装
//获得Jedis
Jedis client = jedisPool.getResource();
try{
client.set("k1", "v1");
client.expire("k1", time) //设置有效时间
client.get("k1"); //获取值
client.del("k1"); //删除值
}catch(Exception e){
e.printStackTrace();
}finally{
jedisPool.returnResource(client); //必须 释放对象池
}
Redis的key和value都支持二进制安全的字符串
保存对象 需要 序列化对象
序列化工具
public class SerializeUtil {
public static byte[] serialize(Object object) {
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
try {
//序列化
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
byte[] bytes = baos.toByteArray();
return bytes;
} catch (Exception e) {
}
return null;
}
public static Object unserialize(byte[] bytes) {
ByteArrayInputStream bais = null;
try {
//反序列化
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
}
return null;
}
}
Spring Data Redis
在Jedis的基础上,提供了对Redis访问的进一步封装。使用SDR,不在需要手动维护连接的建立、释放,对对象序列化提供了默认实现
SDR依赖的的是Spring的高版本3.x
org.springframework.data
spring-data-redis
1.5.2.RELEASE
Spring 配置
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
class="org.springframework.data.redis.core.RedisTemplate">
SDR默认采用JDK的序列化机制 使用JdkSerializationRedisSerializer类,进行对象和byte[]之间的相互转换,就像上面的序列化代码
这里是设置 keySerializer 为StringRedisSerializer 所以使用字符串形式的key
redisTemplate.opsForValue().set(key, value);
redisTemplate.opsForValue().get(key);
redisTemplate.delete(key);
更多api
http://docs.spring.io/spring-data/redis/docs/1.0.x/api/org/springframework/data/redis/core/RedisTemplate.html
Redis 整合 MyBatis