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

来源:互联网 发布:淘宝好的电脑硬件店 编辑:程序博客网 时间:2024/06/02 08:17

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
原创粉丝点击