前言
本文的原文连接是: https://blog.csdn.net/freewebsys/article/details/91410171
未经博主允许不得转载。
博主地址是:http://blog.csdn.net/freewebsys
1,关于mybatis
其实还是有个古老的办法,有简单的办法做cache,但是大家还是习惯去硬编码。
其实不好,应该考虑用统一的方式,非硬编码的方式去做cache。
在加入cache的时候方便,在去掉的时候也方便。
https://www.w3cschool.cn/mybatis/7zy61ilv.html
github:
https://github.com/mybatis/redis-cache
2,使用
修改 mybatis 启用缓存:
然后设置cache:
配置在redis.properties:
redis.host=localhost
redis.port=6379
redis.connectionTimeout=5000
redis.soTimeout=5000
redis.password=
redis.database=0
redis.clientName=
#serializer type(kryo or jdk with jdk being default)
redis.serializer=jdk
其中需要实现 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();
}
而redis 的实现是:
https://github.com/mybatis/redis-cache/blob/master/src/main/java/org/mybatis/caches/redis/RedisCache.java
package org.mybatis.caches.redis;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import org.apache.ibatis.cache.Cache;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
/**
* Cache adapter for Redis.
*
* @author Eduardo Macarron
*/
public final class RedisCache implements Cache {
private final ReadWriteLock readWriteLock = new DummyReadWriteLock();
private String id;
private static JedisPool pool;
private final RedisConfig redisConfig;
private Integer timeout;
public RedisCache(final String id) {
if (id == null) {
throw new IllegalArgumentException("Cache instances require an ID");
}
this.id = id;
redisConfig = RedisConfigurationBuilder.getInstance().parseConfiguration();
pool = new JedisPool(redisConfig, redisConfig.getHost(), redisConfig.getPort(), redisConfig.getConnectionTimeout(),
redisConfig.getSoTimeout(), redisConfig.getPassword(), redisConfig.getDatabase(), redisConfig.getClientName(),
redisConfig.isSsl(), redisConfig.getSslSocketFactory(), redisConfig.getSslParameters(),
redisConfig.getHostnameVerifier());
}
// TODO Review this is UNUSED
private Object execute(RedisCallback callback) {
Jedis jedis = pool.getResource();
try {
return callback.doWithRedis(jedis);
} finally {
jedis.close();
}
}
@Override
public String getId() {
return this.id;
}
@Override
public int getSize() {
return (Integer) execute(new RedisCallback() {
@Override
public Object doWithRedis(Jedis jedis) {
Map<byte[], byte[]> result = jedis.hgetAll(id.getBytes());
return result.size();
}
});
}
@Override
public void putObject(final Object key, final Object value) {
execute(new RedisCallback() {
@Override
public Object doWithRedis(Jedis jedis) {
final byte[] idBytes = id.getBytes();
jedis.hset(idBytes, key.toString().getBytes(), redisConfig.getSerializer().serialize(value));
if (timeout != null && jedis.ttl(idBytes) == -1) {
jedis.expire(idBytes, timeout);
}
return null;
}
});
}
@Override
public Object getObject(final Object key) {
return execute(new RedisCallback() {
@Override
public Object doWithRedis(Jedis jedis) {
return redisConfig.getSerializer().unserialize(jedis.hget(id.getBytes(), key.toString().getBytes()));
}
});
}
@Override
public Object removeObject(final Object key) {
return execute(new RedisCallback() {
@Override
public Object doWithRedis(Jedis jedis) {
return jedis.hdel(id, key.toString());
}
});
}
@Override
public void clear() {
execute(new RedisCallback() {
@Override
public Object doWithRedis(Jedis jedis) {
jedis.del(id);
return null;
}
});
}
@Override
public ReadWriteLock getReadWriteLock() {
return readWriteLock;
}
@Override
public String toString() {
return "Redis {" + id + "}";
}
public void setTimeout(Integer timeout) {
this.timeout = timeout;
}
}
3,总结
主要就是实现了 putObject getObject clear 等方法,把缓存处理下。
其中需要 配置 针对 insert update delate flushCache=“true” 做强制刷新缓存。
然后针对多表关联数据,就没有办法了。useCache=“false” 禁用 cache就行了。
这样在redis 这样的集中式缓存中可以部署多个 tomcat 实例不影响缓存更新了。
主要是使用 hset 实现的。同时增加了超时时间。针对整个大key。
本文的原文连接是:
https://blog.csdn.net/freewebsys/article/details/91410171