系统缓存是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>
网友评论