Springboot redis 做 Mybatis 二级缓存 更新的问题

        最近用到使用redis做mybatis的二级缓存,看网上很多资料大多都是差不多的,但有一个问题就是怎么更新 二级缓存的问题,很多人给出的方案都是直接清空,代码大致为:

 public void clear() {

        rwl.readLock().lock();

        JedisConnection connection = null;

        try {

            connection = jedisConnectionFactory.getConnection();

            connection.flushDb();

            connection.flushAll();

            logger.debug("清除缓存.......");

        } catch (JedisConnectionException e) {

            e.printStackTrace();

        } finally {

            if (connection != null) {

                connection.close();

            }

            rwl.readLock().unlock();

        }

    }

这种方式就相当于清除了所有的缓存数据,但是我们一般想要的不是这种情况,那怎么办呢?

我们知道,在使用redis做mybatis二级缓存的时候,都是要实现Cache类的几个基本的方法的:

getId(),putObject(),getObject(),removeObject(),clear()等方法,这里面涉及到的参数无非就是id,key和value,id一般是对应的mapper全称,也就是命名空间的位置,key就是在这个存储的内容的键,我们需要更新或者删除,都需要用到对应的key值,知道这个问题就好解决了,我们只要找到key值就好了。

但是常规的方式里面的key值是很长的,类似于:["org.apache.ibatis.cache.CacheKey",{"multiplier":37,"hashcode":1658098926,"checksum":-166629244,"count":6,"updateList":["java.util.ArrayList",["com.lebang.phone.mapper.ConfigMapper.getByKey",0,2147483647,"select\n       \n    id, `keys`, `values`\n   \n      from db_config\n      where `keys` = ?",100,"SqlSessionFactoryBean"]],"updateCount":6}],不便于查找,怎么处理呢,所以我们就想着自己生成对应的key,按照一定的既定规则,这样就便于操作了。所以我们的最终方案为:

public class MybatisRedisCache implements Cache {

    private String id;

    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    private RedisTemplate redisTemplate;

    private final String COMMON_CACHE_KEY = "MYBATIS:";

    /**
     * 默认缓存对象的缓存时间为 1 分钟
     **/
    private static final long EXPRIRE_TIME_IN_MINUT = 30;

    public MybatisRedisCache(String id) {
        if (id == null) {
            throw new IllegalArgumentException("缓存对象id是不能为空的");
        }
        this.id = id;
    }

    private RedisTemplate getRedisTemplate() {
        if (redisTemplate == null) {
            redisTemplate = ApplicationContextHolder.getBean("defaultRedisTemplate");
        }
        return redisTemplate;
    }

    @Override
    public String getId() {
        return id;
    }

    @Override
    public void putObject(Object key, Object value) {
        try {
            RedisTemplate redisTemplate = getRedisTemplate();
            //使用redisTemplate得到值操作对象
            ValueOperations operation = redisTemplate.opsForValue();
            //使用值操作对象operation设置缓存对象
            operation.set(getKey(key), value, EXPRIRE_TIME_IN_MINUT, TimeUnit.MINUTES);
//            System.out.println("缓存对象保存成功");
        } catch (Throwable t) {
            System.err.println("缓存对象保存失败" + t);
        }
    }

    @Override
    public Object getObject(Object key) {
        try {
            RedisTemplate redisTemplate = getRedisTemplate();
            ValueOperations operations = redisTemplate.opsForValue();
            Object result = operations.get(getKey(key));
//            System.out.println("获取缓存对象成功");
            return result;
        } catch (Throwable t) {
            System.err.println("缓存对象获取失败" + t);
            return null;
        }
    }

    @Override
    public Object removeObject(Object key) {
        try {
            RedisTemplate redisTemplate = getRedisTemplate();
            redisTemplate.delete(getKey(key));
//            System.out.println("删除缓存对象成功!"+key);
        } catch (Throwable t) {
            System.err.println("删除缓存对象失败!" + t);
        }
        return null;
    }

    @Override
    public void clear() {
        try {
            RedisTemplate redisTemplate = getRedisTemplate();
            Set keys = redisTemplate.keys(getKeys());
            redisTemplate.delete(keys);
            System.out.println("出现新增、修改、删除操作,清空对应Mapper缓存======>"+keys.size());
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 按照一定规则标识key
     */
    private String getKey(Object key) {
        return COMMON_CACHE_KEY + this.id + ":"+ DigestUtils.md5Hex(String.valueOf(key));
    }

    /**所有key*/
    private String getKeys() {
        return COMMON_CACHE_KEY + this.id + ":*";
    }

    @Override
    public int getSize() {
        Long size = getRedisTemplate().boundHashOps(getId()).size();
        return size == null ? 0 : size.intValue();
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
        return readWriteLock;
    }
}

 

 

你可能感兴趣的:(redis)