4 Mybatis Plus使用redis作为二级缓存

Mybatis Plus使用redis作为二级缓存

1. mybatis-plus开启二级缓存

  • mybatis-plus.configuration.cache-enabled=true
#全局设置主键生成策略
mybatis-plus:
  global-config:
    db-config:
      id-type: auto
      logic-delete-field: isDeleted  #全局逻辑删除字段值
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    cache-enabled: true

2. 定义RedisTemplate的bean交给spring管理,这里为了能将对象直接存取到redis中,进行了一些序列化的操作

@Configuration
public class RedisConfig {

    // 自己定义了一个 RedisTemplate
    @Bean(value = "redisTemplate")
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        // 我们为了自己开发方便,一般直接使用 <String, Object>
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);

        // Json序列化配置
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // String 的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();

        return template;
    }

}

3. 自定义自己的缓存管理

@Slf4j
public class MybatisRedisCache implements Cache {


    /**
     * 读写锁
     */
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);

    /**
     * 这里使用了redis缓存,使用springboot自动注入
     */
    private RedisTemplate<String, Object> redisTemplate;

    private String id;

    public MybatisRedisCache(final String id) {
        if (id == null) {
            throw new IllegalArgumentException("Cache instances require an ID");
        }
        this.id = id;
    }

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

    @Override
    public void putObject(Object key, Object value) {
        if (redisTemplate == null) {
            //由于启动期间注入失败,只能运行期间注入,这段代码可以删除
            redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
        }
        try {
            if (value != null) {
                log.info("key>>>>>>>>>>>>>>>>>>>>>>> {} ", key);
                log.info("value>>>>>>>>>>>>>>>>>>>>>>> {}", value);
                redisTemplate.opsForValue().set(String.valueOf(key), value);
            }
        }catch (Exception e) {
            e.printStackTrace();
            log.error("缓存set出错 ");
        }
    }

    @Override
    public Object getObject(Object key) {
        if (redisTemplate == null) {
            //由于启动期间注入失败,只能运行期间注入,这段代码可以删除
            redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
        }
        try {
            if (key != null) {
                return redisTemplate.opsForValue().get(key.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("缓存get出错 ");
        }
        return null;
    }

    @Override
    public Object removeObject(Object key) {
        if (redisTemplate == null) {
            //由于启动期间注入失败,只能运行期间注入,这段代码可以删除
            redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
        }
        try {
            if (key != null) {
                redisTemplate.delete(key.toString());
            }
        }catch (Exception e) {
            e.printStackTrace();
            log.error("缓存delete出错 ");
        }
        return null;
    }

    @Override
    public void clear() {
        log.debug("清空缓存");
        if (redisTemplate == null) {
            redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
        }
        try {
            Set<String> keys = redisTemplate.keys("*:" + this.id + "*");
            if (!CollectionUtils.isEmpty(keys)) {
                redisTemplate.delete(keys);
            }
        }catch (Exception e) {
            e.printStackTrace();
            log.error("缓存清空缓存出错 ");
        }
    }

    @Override
    public int getSize() {
        if (redisTemplate == null) {
            //由于启动期间注入失败,只能运行期间注入,这段代码可以删除
            redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
        }
        try {
            Long size = redisTemplate.execute((RedisCallback<Long>) RedisServerCommands::dbSize);
            return size.intValue();
        }catch (Exception e) {
            e.printStackTrace();
            log.error("缓存size存出错 ");
        }
        return 0;
    }

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

4. 在mapper上加上注解@CacheNamespace

@Repository
@CacheNamespace(implementation= MybatisRedisCache.class,eviction= MybatisRedisCache.class)
public interface PfParkingMapper extends BaseMapper<Parking> {}

如果调用该mapper下的方法,那么会使用redis缓存

posted @ 2020-08-31 11:44  SweetBaby。  阅读(529)  评论(0编辑  收藏  举报