自定义缓存

Exisi 2021-03-27 08:14:01
Categories: Tags:
  • 除了上述自定义缓存的方式,你也可以通过实现你自己的缓存,或为其他第三方缓存方案创建适配器,来完全覆盖缓存行为。

 

<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;

}

 

 

 

来自 <https://mybatis.org/mybatis-3/zh/sqlmap-xml.html#cache>