- 除了上述自定义缓存的方式,你也可以通过实现你自己的缓存,或为其他第三方缓存方案创建适配器,来完全覆盖缓存行为。
<cache type="com.domain.something.MyCustomCache"/>
- 这个示例展示了如何使用一个自定义的缓存实现。type 属性指定的类必须实现 org.apache.ibatis.cache.Cache 接口,且提供一个接受 String 参数作为 id 的构造器。 这个接口是 MyBatis 框架中许多复杂的接口之一,但是行为却非常简单。
public interface Cache {
String getId();
int getSize();
void put
Object(Object key, Object value);
Object getObject(Object key);
boolean hasKey(Object key);
Object removeObject(Object key);
void clear();
}
- 以下以通过自定义通过 redis 进行缓存为例
示例
- mapper.xml
<mapper namespace="com.example.demo.mapper.StudentMapper"> <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" type="com.example.demo.mapper.RedisCache"> </cache> </mapper>
|
|
- RedisCache.java
public class RedisCache implements Cache{ /** * 序列化 * 封装一个方法 用来给对象写到redis里面 * jedis.set(主键,objectTobyteArray(student对象)) * @throws IOException */ public static byte[] objectToByteArray(Object object) throws IOException{ ByteOutputStream boss = new ByteOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(boss); oos.writeObject(object); return boss.getBytes(); }
/** * 反序列化 * byte [] bt=get("主键") * student s =byteArrayToObject(bt) * 反序列化字节数组为对象 * @throws IOException * @throws ClassNotFoundException */ public static Object byteArrayToObject(byte[] bt) throws Exception{ ByteInputStream bis = new ByteInputStream(bt, bt.length); ObjectInputStream ois = new ObjectInputStream(bis); return ois.readObject(); }
/** * 操作redis对象 */ Jedis jedis = new Jedis("localhost", 6379);
// 缓存的id private String cacheId;
// 需要一个构造方法 public RedisCache(String cacheId){ this.cacheId = cacheId; }
public String getId(){ return cacheId; }
/** * mybatis读取数据时 将数据库中读取的数据 通过putObject设置到缓存中 */ public void putObject(Object key, Object value){ try{ //写入到redis 通过用byte数组的方式写入到redis jedis.set(objectToByteArray(key), objectToByteArray(value)); } catch (IOException e){ e.printStackTrace(); } }
/** * mybatis自动调用getObject检查是否缓存中存在 */ public Object getObject(Object key){ try{ byte[] bs = jedis.get(objectToByteArray(key)); if (bs == null){ return null; } return byteArrayToObject(bs); } catch (Exception e){ e.printStackTrace(); } return null; }
/** * mybatis缓存策略 自动判断内存大小,内存不够时,调用该方法,然后来决定删除一些过期或者久远的数据 * @param key * @return */ public Object removeObject(Object key){ Object object = getObject(key); try{ jedis.del(objectToByteArray(key)); } catch (IOException e){ e.printStackTrace(); } return object; }
// 清空缓存 session被关闭的时候会调用这个方法 一般不要去清理他 public void clear(){ // jedis.flushDB(); }
public int getSize(){ return 0; }
// 二级缓存中的锁 public ReadWriteLock getReadWriteLock(){ return new ReentrantReadWriteLock(); } } |
- 为了对你的缓存进行配置,只需要简单地在你的缓存实现中添加公有的 JavaBean 属性,然后通过 cache 元素传递属性值,例如,下面的例子将在你的缓存实现上调用一个名为 setCacheFile(String file) 的方法:
<cache type="com.domain.something.MyCustomCache">
<property name="cacheFile" value="/tmp/my-custom-cache.tmp"/>
</cache>
- 你可以使用所有简单类型作为 JavaBean 属性的类型,MyBatis 会进行转换。 你也可以使用占位符(如 ${cache.file}),以便替换成在配置文件属性中定义的值。
- 从版本 3.4.2 开始,MyBatis 已经支持在所有属性设置完毕之后,调用一个初始化方法。 如果想要使用这个特性,请在你的自定义缓存类里实现 org.apache.ibatis.builder.InitializingObject 接口
public interface InitializingObject {
void initialize() throws Exception;
}