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

redis( 3 )redis与Mybatis的无缝整合让MyBatis透明的管理缓存

2015-08-30 10:32 726 查看
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代理对象,在对数据发生更改的时候,会出错。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: