在mybatis中,缓存的功能由根接口Cache(org.apache.ibatis.cache.Cache)定义。整个体系采用装饰器设计模式, 数据存储和缓存的基本功能由PerpetualCache(org.apache.ibatis.cache.impl.PerpetualCache) 永久缓存实现,然后通过一系列的装饰器来对PerpetualCache永久缓存进行缓存策略等方便的控制用于装饰PerpetualCache的标准装饰器共有8个(全部在org.apache.ibatis.cache.decorators包中):
1.FifoCache:先进先出算法,缓存回收策略<cache eviction="FIFO" flushInterval="10000" size="1024" readOnly="true" type="com.sdzn.basedata.controller.RedisCache"></cache>
2.LoggingCache:输出缓存命中的日志信息
3.LruCache:最近最少使用算法,缓存回收策略
<cache eviction="LRU" flushInterval="10000" size="1024" readOnly="true" type="com.sdzn.basedata.controller.RedisCache"></cache>
4.ScheduledCache:调度缓存,负责定时清空缓存
5.SerializedCache:缓存序列化和反序列化存储
6.SoftCache:基于软引用实现的缓存管理策略
7.SynchronizedCache:同步的缓存装饰器,用于防止多线程并发访问
8.WeakCache:基于弱引用实现的缓存管理策略
另外,还有一个特殊的装饰器TransactionalCache:事务性的缓存
配置Mybatis缓存
1、第一步:在Mapper.XML配置文件增加缓存配置;
如:
<cache eviction="FIFO" flushInterval="10000" size="1024" readOnly="true" type="com.sdzn.basedata.controller.RedisCache"></cache>
2、第二步:创建com.sdzn.basedata.controller.RedisCache 缓存类;此类必须实现Cache 【org.apache.ibatis.cache.Cache】接口;
/**
*
* redis缓存处理类
*
* <p>用于根据sql语句将sql及对应的数据存入redis中
* @author 朱家田 2016年9月22日
* @see Cache
* @since 1.0
*/
public class RedisCache implements Cache{
private Jedis redisClient = createReids();
private String id;
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
@Override
public String getId() {
// TODO Auto-generated method stub
return id;
}
public RedisCache(final String id){
if (id == null) {
throw new IllegalArgumentException("Cache instances require an ID");
}
this.id = id;
}
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) {
e.printStackTrace();
}
return null;
}
@Override
public void putObject(Object key, Object value) {
System.err.println("put key" + key);
redisClient.set(serialize(key.toString()),serialize(value));
}
public static Object unserialize(byte[] bytes) {
if (bytes == null)
return null;
ByteArrayInputStream bais = null;
try {
// 反序列化
bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public Object getObject(Object key) {
System.out.println("get key");
Object value = unserialize(redisClient.get(serialize(key.toString())));
System.out.println(value);
return value;
}
@Override
public Object removeObject(Object key) {
System.err.println("remove key" + key);
return redisClient.expire(serialize(key.toString()), 0);
}
@Override
public void clear() {
System.err.println("clear all data");
redisClient.flushDB();
}
@Override
public int getSize() {
return Integer.valueOf(redisClient.dbSize().toString());
}
@Override
public ReadWriteLock getReadWriteLock() {
// TODO Auto-generated method stub
return readWriteLock;
}
protected static Jedis createReids() {
JedisPool pool = new JedisPool(new JedisPoolConfig(), "192.168.0.200", 6379,10000,"my_redis");
return pool.getResource();
}
}
3、第三步 将记录数据库数据的Bean类实现Serializable接口