redis-cache中的callback
这个是mybatis/redis-cache中关键类 RedisCache 的源码
/** * Copyright 2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 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; public RedisCache(final String id) { if (id == null) { throw new IllegalArgumentException("Cache instances require an ID"); } this.id = id; RedisConfig redisConfig = RedisConfigurationBuilder.getInstance().parseConfiguration(); pool = new JedisPool(redisConfig, redisConfig.getHost(), redisConfig.getPort(), redisConfig.getConnectionTimeout(), redisConfig.getSoTimeout(), redisConfig.getPassword(), redisConfig.getDatabase(), redisConfig.getClientName()); } 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.toString().getBytes()); return result.size(); } }); } @Override public void putObject(final Object key, final Object value) { execute(new RedisCallback() { @Override public Object doWithRedis(Jedis jedis) { jedis.hset(id.toString().getBytes(), key.toString().getBytes(), SerializeUtil.serialize(value)); return null; } }); } @Override public Object getObject(final Object key) { return execute(new RedisCallback() { @Override public Object doWithRedis(Jedis jedis) { return SerializeUtil.unserialize(jedis.hget(id.toString().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.toString(), key.toString()); } }); } @Override public void clear() { execute(new RedisCallback() { @Override public Object doWithRedis(Jedis jedis) { jedis.del(id.toString()); return null; } }); } @Override public ReadWriteLock getReadWriteLock() { return readWriteLock; } @Override public String toString() { return "Redis {" + id + "}"; } }
可以看到其中大量使用了callback方法来操作redis, 但是调用本身是同步的, 其中能想到的唯一好处, 就是省下了每次调用之后的close() - 不知道是否还有别的优点.
MyBatis使用Redis作为Cache
如果将MyBatis内建Cache换为Redis, 需要在重启MyBatis所在服务时, 同时对Redis所在的db进行flushdb, 在部署脚本中增加一句
echo 'Cleaning Redis cache' redis-cli -h 192.168.1.18 -p 6379 -a foobar -n 10 flushdb # -h 服务器地址 # -p 端口 # -a 口令 # -n db编号