- import java.util.HashSet;
- import java.util.Set;
- import java.util.concurrent.locks.ReadWriteLock;
- import java.util.concurrent.locks.ReentrantReadWriteLock;
- import org.apache.ibatis.cache.Cache;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import redis.clients.jedis.BinaryJedisCluster;
- import redis.clients.jedis.HostAndPort;
- import redis.clients.jedis.JedisPoolConfig;
- /**
- * mybatis整合redis-cluster
- * @author zaqzaq
- * 2015年2月5日
- *
- */
- public class MybatisRedisCache implements Cache {
- private static Logger logger = LoggerFactory.getLogger(MybatisRedisCache.class);
- private static BinaryJedisCluster redisClient=createReids();
- /** The ReadWriteLock. */
- private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
- private String id;
- private Set<String> keys=new HashSet<String>();
- public MybatisRedisCache(final String id) {
- if (id == null) {
- throw new IllegalArgumentException("Cache instances require an ID");
- }
- logger.debug("redis>>>>MybatisRedisCache:id="+id);
- this.id = id;
- }
- @Override
- public String getId() {
- return this.id;
- }
- @Override
- public int getSize() {
- //在集群情况下只返回当前主机下的dbsize
- // int i=Integer.valueOf(redisClient.dbSize().toString());
- logger.debug("mybatis cache redis>>>>getSize:"+keys.size());
- return keys.size();
- }
- @Override
- public void putObject(Object key, Object value) {
- logger.debug("redis>>>>putObject:"+key+"="+value);
- redisClient.set(key.toString(), SerializeUtil.serialize(value));
- if (!keys.contains(key.toString())){
- keys.add(key.toString());
- }
- }
- @Override
- public Object getObject(Object key) {
- Object value = SerializeUtil.unserialize(redisClient.getBytes(key.toString()));
- logger.debug("redis>>>>getObject:"+key+"="+value);
- if (!keys.contains(key.toString())){
- keys.add(key.toString());
- }
- return value;
- }
- @Override
- public Object removeObject(Object key) {
- logger.debug("redis>>>>removeObject:"+key);
- keys.remove(key.toString());
- return redisClient.expire(key.toString(),0);
- }
- @Override
- public void clear() {
- logger.debug("redis>>>>clearObject:"+id);
- //清除namespace下的所有缓存
- for(String key:keys){
- redisClient.expire(key.toString(),0);
- }
- keys.clear();
- //禁止使用 redisClient.flushDB();
- }
- @Override
- public ReadWriteLock getReadWriteLock() {
- return readWriteLock;
- }
- protected static BinaryJedisCluster createReids(){
- //
- JedisPoolConfig config = new JedisPoolConfig();
- //控制一个pool可分配多少个jedis实例,通过pool.getResource()来获取;
- //如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
- config.setMaxTotal(500);
- //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
- config.setMaxIdle(5);
- //表示当borrow(引入)一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;
- config.setMaxWaitMillis(1000 * 100);
- //在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
- config.setTestOnBorrow(true);
- int time_out=12*1000;
- Set<HostAndPort> hostAndPorts=new HashSet<HostAndPort>();
- hostAndPorts.add(new HostAndPort("zaqzaq1", 6379));
- hostAndPorts.add(new HostAndPort("zaqzaq2", 6379));
- hostAndPorts.add(new HostAndPort("zaqzaq3", 6379));
- return new BinaryJedisCluster(hostAndPorts,time_out,config);
- }
- }
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- public class SerializeUtil {
- public static byte[] serialize(Object object) {
- ObjectOutputStream oos = null;
- ByteArrayOutputStream baos = null;
- try {
- // 序列化
- baos = new ByteArrayOutputStream();
- oos = new ObjectOutputStream(baos);
- oos.writeObject(object);
- byte[] bytes = baos.toByteArray();
- return bytes;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- public static Object unserialize(byte[] bytes) {
- ByteArrayInputStream bais = null;
- try {
- // 反序列化
- bais = new ByteArrayInputStream(bytes);
- ObjectInputStream ois = new ObjectInputStream(bais);
- return ois.readObject();
- } catch (Exception e) {
- }
- return null;
- }
- }
- <settings>
- <!-- 这个配置使全局的映射器启用或禁用缓存 -->
- <setting name="cacheEnabled" value="true" />
- <!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->
- <setting name="multipleResultSetsEnabled" value="true"/>
- <!-- 配置默认的执行器。SIMPLE 执行器没有什么特别之处。REUSE 执行器重用预处理语句。BATCH 执行器重用语句和批量更新 -->
- <setting name="defaultExecutorType" value="REUSE" />
- <!-- 全局启用或禁用延迟加载。当禁用时,所有关联对象都会即时加载。 -->
- <setting name="lazyLoadingEnabled" value="false" />
- <setting name="aggressiveLazyLoading" value="true" />
- <!-- <setting name="enhancementEnabled" value="true"/> -->
- <!-- 设置超时时间,它决定驱动等待一个数据库响应的时间。 -->
- <setting name="defaultStatementTimeout" value="25000" />
- </settings>
- <!-- 缓存 -->
- <cache eviction="LRU" type="com.cloud.core.cache.MybatisRedisCache" readOnly="false" />
- sql语句上特殊配置的属性有useCache,flushCache