mybatis的二级缓存sessionFactory缓存集成redis
2016-10-23 17:18
531 查看
1、RedisCache.java
2、在看ehcache-mybatis的源码 它真正使用cache的方式是通过集成org.apache.ibatis.cache.decorators.LoggingCache 这个类实现的,照猫画虎,直接我们也继承
3、因为使用MyBatis的二级缓存,所以要缓存的类,必须开启cache
4、在mybatis的核心文件中开启缓存
注意着两个属性,需要把属性延迟加载和关联对象加载给关闭了,不然放进redis中的cglib代理对象,在对数据发生更改的时候,会出错。
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" />
相关文章推荐
- Redis集成到Spring做mybatis做二级缓存
- Redis集成到Spring做mybatis做二级缓存
- mybatis使用redis做二级缓存
- 3-SSM框架整合Redis做MyBatis二级缓存
- Redis实现Mybatis的二级缓存
- 使用Redis做MyBatis的二级缓存
- springboot+mybatis+redis 二级缓存问题实例详解
- Spring boot使用Redis集群替换mybatis二级缓存
- Redis实现Mybatis的二级缓存
- mybatis + spring + redis(二级缓存)整合
- mybatis结合redis实战二级缓存(六)
- 使用Redis做MyBatis的二级缓存
- 使用redis做mybaties的二级缓存(2)-Mybatis 二级缓存小心使用
- SpringMVC + MyBatis + Mysql + Redis(作为二级缓存) 配置
- 使用redis作为mybatis的二级缓存
- AAA spring 集成mybatis使用二级缓存 (下篇)
- 使用Redis做MyBatis的二级缓存
- redis与ssm整合方法(mybatis二级缓存)
- mybatis整合redies,使用redis作为二级缓存
- SpringMVC + MyBatis + Mysql + Redis(作为二级缓存) 配置