mybatis的二级缓存sessionFactory缓存集成redis

1、RedisCache.java

package cn.seafood.cache;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.cache.Cache;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.exceptions.JedisConnectionException;
import cn.seafood.util.PropertiesLoader;

/**
 * 
* @ClassName: RedisCache
* @Description: TODO(使用第三方缓存服务器redis,处理二级缓存)
*
 */
public class RedisCache   implements Cache {
        private static Log log = LogFactory.getLog(RedisCache.class);
        /** The ReadWriteLock. */
        private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

        private String id;
        public RedisCache(final String id) {
                if (id == null) {
                        throw new IllegalArgumentException("必须传入ID");
                }
                log.debug("MybatisRedisCache:id=" + id);
                this.id=id;
        }

        @Override
        public String getId() {
                return this.id;
        }

        @Override
        public int getSize() {
                Jedis jedis = null;
                JedisPool jedisPool = null;
                int result = 0;
                boolean borrowOrOprSuccess = true;
                try {
                        jedis   = CachePool.getInstance().getJedis();
                        jedisPool = CachePool.getInstance().getJedisPool();
                        result = Integer.valueOf(jedis.dbSize().toString());
                } catch (JedisConnectionException e) {
                        borrowOrOprSuccess = false;
                        if (jedis != null)
                                jedisPool.returnBrokenResource(jedis);
                } finally {
                        if (borrowOrOprSuccess)
                                jedisPool.returnResource(jedis);
                }
                return result;

        }

        @Override
        public void putObject(Object key, Object value) {
                if(log.isDebugEnabled())
                log.debug("putObject:" + key.hashCode() + "=" + value);
                if(log.isInfoEnabled())
                log.info("put to redis sql :" +key.toString());
                Jedis jedis = null;
                JedisPool jedisPool = null;
                boolean borrowOrOprSuccess = true;
                try {
                        jedis   = CachePool.getInstance().getJedis();
                        jedisPool = CachePool.getInstance().getJedisPool();
                        jedis.set(SerializeUtil.serialize(key.hashCode()), SerializeUtil.serialize(value));
                } catch (JedisConnectionException e) {
                        borrowOrOprSuccess = false;
                        if (jedis != null)
                                jedisPool.returnBrokenResource(jedis);
                } finally {
                        if (borrowOrOprSuccess)
                                jedisPool.returnResource(jedis);
                }

        }

        @Override
        public Object getObject(Object key) {
                Jedis jedis = null;
                JedisPool jedisPool = null;
                Object value = null;
                boolean borrowOrOprSuccess = true;
                try {
                        jedis   = CachePool.getInstance().getJedis();
                        jedisPool = CachePool.getInstance().getJedisPool();
                        value  = SerializeUtil.unserialize(jedis.get(SerializeUtil.serialize(key.hashCode())));
                } catch (JedisConnectionException e) {
                        borrowOrOprSuccess = false;
                        if (jedis != null)
                                jedisPool.returnBrokenResource(jedis);
                } finally {
                        if (borrowOrOprSuccess)
                                jedisPool.returnResource(jedis);
                }
                if(log.isDebugEnabled())
                log.debug("getObject:" + key.hashCode() + "=" + value);
                return value;
        }

        @Override
        public Object removeObject(Object key) {
                Jedis jedis = null;
                JedisPool jedisPool = null;
                Object value = null;
                boolean borrowOrOprSuccess = true;
                try {
                        jedis   = CachePool.getInstance().getJedis();
                        jedisPool = CachePool.getInstance().getJedisPool();
                        value  = jedis.expire(SerializeUtil.serialize(key.hashCode()), 0);
                } catch (JedisConnectionException e) {
                        borrowOrOprSuccess = false;
                        if (jedis != null)
                                jedisPool.returnBrokenResource(jedis);
                } finally {
                        if (borrowOrOprSuccess)
                                jedisPool.returnResource(jedis);
                }
                if(log.isDebugEnabled())
                log.debug("getObject:" + key.hashCode() + "=" + value);
                return value;
        }

        @Override
        public void clear() {
                Jedis jedis = null;
                JedisPool jedisPool = null;
                boolean borrowOrOprSuccess = true;
                try {
                        jedis   = CachePool.getInstance().getJedis();
                        jedisPool = CachePool.getInstance().getJedisPool();
                        jedis.flushDB();
                        jedis.flushAll();
                } catch (JedisConnectionException e) {
                        borrowOrOprSuccess = false;
                        if (jedis != null)
                                jedisPool.returnBrokenResource(jedis);
                } finally {
                        if (borrowOrOprSuccess)
                                jedisPool.returnResource(jedis);
                }
        }

        @Override
        public ReadWriteLock getReadWriteLock() {
                return readWriteLock;
        }
       /**
        * 
       * @ClassName: CachePool
       * @Description: TODO(单例Cache池)
       *
        */
        public static class CachePool {
                JedisPool pool;
                private static final CachePool cachePool = new CachePool();

                public static CachePool getInstance(){
                        return cachePool;
                }
                private CachePool() {
                        JedisPoolConfig config = new JedisPoolConfig();
                        config.setMaxIdle(100);
                        config.setMaxWaitMillis(1000l);
                         PropertiesLoader pl =  new PropertiesLoader("classpath:config/redis.properties");
                         pool = new JedisPool(config,pl.getProperty("redisvip"));
                }
                public  Jedis getJedis(){
                        Jedis jedis = null;
                        boolean borrowOrOprSuccess = true;
                        try {
                                jedis = pool.getResource();
                        } catch (JedisConnectionException e) {
                                borrowOrOprSuccess = false;
                                if (jedis != null)
                                        pool.returnBrokenResource(jedis);
                        } finally {
                                if (borrowOrOprSuccess)
                                        pool.returnResource(jedis);
                        }
                        jedis = pool.getResource();
                        return jedis;
                }

                public JedisPool getJedisPool(){
                        return this.pool;
                }

        }


        public static 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) {
                        if(bytes == null)return null;
                        ByteArrayInputStream bais = null;
                        try {
                                // 反序列化
                                bais = new ByteArrayInputStream(bytes);
                                ObjectInputStream ois = new ObjectInputStream(bais);
                                return ois.readObject();
                        } catch (Exception e) {
                                e.printStackTrace();
                        }
                        return null;
                }
        }
}

2、在看ehcache-mybatis的源码 它真正使用cache的方式是通过集成org.apache.ibatis.cache.decorators.LoggingCache 这个类实现的,照猫画虎,直接我们也继承

public class LoggingRedisCache extends LoggingCache {

        public LoggingRedisCache(String id) {
                super(new RedisCache(id));
        }

}

3、因为使用MyBatis的二级缓存,所以要缓存的类,必须开启cache

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE  mapper  PUBLIC  "-//mybatis.org//DTD  Mapper  3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mvc.model.Account">
    <!-- redis缓存 -->
    <cache eviction="LRU" type="com.mvc.cache.LoggingRedisCache"/><br>
    <select id="loginAccount" parameterType="account" resultType="account" useCache="true">
        select * from account a where a.login=#{login} and a.pass=#{pass}
    </select>
</mapper>

4、在mybatis的核心文件中开启缓存

<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>

注意着两个属性,需要把属性延迟加载和关联对象加载给关闭了,不然放进redis中的cglib代理对象,在对数据发生更改的时候,会出错。

<setting name="lazyLoadingEnabled" value="false" />

<setting name="aggressiveLazyLoading" value="true" />
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值