redis的安装http://liuyieyer.iteye.com/blog/2078093
redis的主从高可用 http://liuyieyer.iteye.com/blog/2078095
Mybatis 的使用不多说。
Mybatis为了方便我们扩展缓存定义了一个Cache接口,看看ehcache-mybatis的源码就明白了。我们要使用自己的cache同样的实现Cache接口即可。直接上代码
- 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 这个类实现的,照猫画虎,直接我们也继承
- public class LoggingRedisCache extends LoggingCache {
- public LoggingRedisCache(String id) {
- super(new RedisCache(id));
- }
- }
在mapper.xml中添加如下cache标签
- <!-- 启用缓存 -->
- <cache type="cn.seafood.cache.LoggingRedisCache" />
在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>
<setting name="lazyLoadingEnabled" value="false" />
<setting name="aggressiveLazyLoading" value="true" />
注意着两个属性,需要把属性延迟加载和关联对象加载给关闭了,不然放进redis中的cglib代理对象,在对数据发生更改的时候,会出错。