MyBatis自定义缓存

2020-07-19  本文已影响0人  Doooook

系统缓存是MyBatis应用机器上的本地缓存,但是在大型服务器上,会使用各类不同的缓存服务器,这个时候我们可以定制缓存,比如现在十分流行的Redis缓存。我们需要实现MyBatis为我们提供的接口org.apache.ibatis.cache.Cache:

public interface Cache {

  /**
   * @return The identifier of this cache
   */
  String getId();

  /**
   * @param key Can be any object but usually it is a {@link CacheKey}
   * @param value The result of a select.
   */
  void putObject(Object key, Object value);

  /**
   * @param key The key
   * @return The object stored in the cache.
   */
  Object getObject(Object key);

  /**
   * As of 3.3.0 this method is only called during a rollback 
   * for any previous value that was missing in the cache.
   * This lets any blocking cache to release the lock that 
   * may have previously put on the key.
   * A blocking cache puts a lock when a value is null 
   * and releases it when the value is back again.
   * This way other threads will wait for the value to be 
   * available instead of hitting the database.
   *
   * 
   * @param key The key
   * @return Not used
   */
  Object removeObject(Object key);

  /**
   * Clears this cache instance
   */  
  void clear();

  /**
   * Optional. This method is not called by the core.
   * 
   * @return The number of elements stored in the cache (not its capacity).
   */
  int getSize();
  
  /** 
   * Optional. As of 3.2.6 this method is no longer called by the core.
   *  
   * Any locking needed by the cache must be provided internally by the cache provider.
   * 
   * @return A ReadWriteLock 
   */
  ReadWriteLock getReadWriteLock();

因为每种缓存都有其不同的特点,上面的接口都需要我们去实现,假设我们已经有一个实现类:

import org.apache.ibatis.cache.Cache;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author Doooook
 * @date 2020/07/14
 */
public class MyBatisCache implements Cache {

    private ReadWriteLock lock = new ReentrantReadWriteLock();
    private ConcurrentHashMap<Object, Object> cache = new ConcurrentHashMap<Object, Object>();
    private String id;
    private String host;

    public MyBatisCache() {
        System.out.println("初始化-1!");
    }

    /**
     * 必须有该构造函数
     *
     * @param id
     */
    public MyBatisCache(String id) {
        System.out.println("初始化-2!");
        this.id = id;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    /**
     * 获取缓存编号
     *
     * @return
     */
    @Override
    public String getId() {
        // id形如:com.pengjs.kkb.mybatis.mapper.StudentMapper
        System.out.println("得到ID:" + id);
        return id;
    }

    /**
     * 获取缓存对象的大小
     *
     * @return
     */
    @Override
    public int getSize() {
        System.out.println("获取缓存大小!");
        return 0;
    }

    /**
     * 保存key值缓存对象
     *
     * @param key
     * @param value
     */
    @Override
    public void putObject(Object key, Object value) {
        System.out.println("往缓存中添加元素:key=" + key + ", value=" + value);
        cache.put(key, value);
    }

    /**
     * 通过KEY
     *
     * @param key
     * @return
     */
    @Override
    public Object getObject(Object key) {
        System.out.println("通过KEY获取值:" + key);
        System.out.println("OVER");
        System.out.println("=======================================================");
        System.out.println("值为:" + cache.get(key));
        System.out.println("=====================OVER==============================");
        return cache.get(key);
    }

    /**
     * 通过key删除缓存对象
     *
     * @param key
     * @return
     */
    @Override
    public Object removeObject(Object key) {
        System.out.println("移除缓存对象:" + key);
        return cache.remove(key);
    }

    /**
     * 清空缓存
     */
    @Override
    public void clear() {
        System.out.println("清除缓存!");
        cache.clear();
    }

    /**
     * 获取缓存的读写锁
     *
     * @return
     */
    @Override
    public ReadWriteLock getReadWriteLock() {
        System.out.println("获取锁对象!!!");
        return lock;
    }
}

完成缓存的实现类以后,按照如下配置,就可以使用自定义的配置了:

  <cache type="com.pengjs.kkb.mybatis.cache.MyBatisCache">
    <!-- 如果在MyBatisCache中增加setHost(String host)方法,那么他在被初始化的时候会被调用,这样可以自定义一些外部参数 -->
    <property name="host" value="localhost"/>
  </cache>
上一篇 下一篇

猜你喜欢

热点阅读