您的位置:首页 > 数据库 > Redis

redis+mybatis+spring

2015-08-30 12:30 681 查看
redis的安装http://liuyieyer.iteye.com/blog/2078093

redis的主从高可用 http://liuyieyer.iteye.com/blog/2078095

Mybatis 的使用不多说。

Mybatis为了方便我们扩展缓存定义了一个Cache接口,看看ehcache-mybatis的源码就明白了。我们要使用自己的cache同样的实现Cache接口即可。直接上代码

Java代码


public class RedisCache implements Cache {

private static Log logger = LogFactory.getLog(RedisCache.class);

private Jedis redisClient = createClient();

/** The ReadWriteLock. */

private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();



private String id;

public RedisCache(final String id) {

if (id == null) {

throw new IllegalArgumentException("Cache instances require an ID");

}

logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>MybatisRedisCache:id=" + id);

this.id = id;

}



@Override

public String getId() {

return this.id;

}



@Override

public int getSize() {

return Integer.valueOf(redisClient.dbSize().toString());

}



@Override

public void putObject(Object key, Object value) {

logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>putObject:" + key + "=" + value);

redisClient.set(SerializeUtil.serialize(key.toString()), SerializeUtil.serialize(value));

}



@Override

public Object getObject(Object key) {

Object value = SerializeUtil.unserialize(redisClient.get(SerializeUtil.serialize(key.toString())));

logger.debug(">>>>>>>>>>>>>>>>>>>>>>>>getObject:" + key + "=" + value);

return value;

}



@Override

public Object removeObject(Object key) {

return redisClient.expire(SerializeUtil.serialize(key.toString()), 0);

}



@Override

public void clear() {

redisClient.flushDB();

}



@Override

public ReadWriteLock getReadWriteLock() {

return readWriteLock;

}



protected static Jedis createClient() {

try {

JedisPool pool = new JedisPool(new JedisPoolConfig(), "172.60.0.172");

return pool.getResource();

} catch (Exception e) {

e.printStackTrace();

}

throw new RuntimeException("初始化连接池错误");

}







}





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;

}

}



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

Java代码


public class LoggingRedisCache extends LoggingCache {



public LoggingRedisCache(String id) {

super(new RedisCache(id));

}



}



在mapper.xml中添加如下cache标签



Xml代码


<!-- 启用缓存 -->

<cache type="cn.seafood.cache.LoggingRedisCache" />

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

Xml代码


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



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

<setting name="aggressiveLazyLoading" value="true" />

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





在上一篇文中的Cahe类存在各种问题如:一直使用同一个连接,每次都创建新的Cache,项目中老是爆出connection timeout 的异常,存储的key过长等等一系列的问题,解决问题最好的办法就是看源码和看官方的文档说明,jedis的文档还是够用的,接下来把cache也改造以下附上代码。

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,处理二级缓存)

* @author LiuYi

* @date 2014年6月9日 下午1:37:46

*

*/

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

* @author LiuYi

* @date 2014年6月17日 上午10:50:52

*

*/

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;

}

}

}

参考链接:http://liuyieyer.iteye.com/blog/2081382
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: