zoukankan      html  css  js  c++  java
  • redis(四)redis与Mybatis的无缝整合让MyBatis透明的管理缓存

    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代理对象,在对数据发生更改的时候,会出错。

  • 相关阅读:
    本地计算机 上的 Redis Server 服务启动后停止
    RabbitMQ 命令行
    mysql ORDER BY 中文出现错误问题
    使用javascript纯前端导出excel
    软件测试概念学习
    excel控件只为简单写入数据表--github找到ExcelUtil笔记
    快速创建Spring web项目
    PQGrid商业化的表格组件
    mybatis传入参数为0被误认为是空字符串的解决方法
    MyBatis like报错
  • 原文地址:https://www.cnblogs.com/duyinqiang/p/5696408.html
Copyright © 2011-2022 走看看