• mybatis plus使用redis作为二级缓存


    建议缓存放到 service 层,你可以自定义自己的 BaseServiceImpl 重写注解父类方法,继承自己的实现。为了方便,这里我们将缓存放到mapper层。mybatis-plus整合redis作为二级缓存与mybatis整合redis略有不同。

    1. mybatis-plus开启二级缓存

    mybatis-plus.configuration.cache-enabled=true

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

    @Bean(value = "redisTemplate")
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
            RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
            redisTemplate.setConnectionFactory(connectionFactory);
            //Use Jackson 2Json RedisSerializer to serialize and deserialize the value of redis (default JDK serialization)
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            //将类名称序列化到json串中
            objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            //设置输入时忽略JSON字符串中存在而Java对象实际没有的属性
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
    
            //Use String RedisSerializer to serialize and deserialize the key value of redis
            RedisSerializer redisSerializer = new StringRedisSerializer();
            //key
            redisTemplate.setKeySerializer(redisSerializer);
            redisTemplate.setHashKeySerializer(redisSerializer);
            //value
            redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
            redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
    
            redisTemplate.afterPropertiesSet();
            return redisTemplate;
    
        }
    

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

    package com.qctchina.headsetserver.config;
    
    import com.qctchina.headsetserver.util.SpringUtil;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.ibatis.cache.Cache;
    import org.springframework.data.redis.connection.RedisServerCommands;
    import org.springframework.data.redis.core.RedisCallback;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.util.CollectionUtils;
    
    import java.util.Set;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    /**
     * @author shuangyueliao
     * @create 2019/9/10 14:02
     * @Version 0.1
     */
    @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");
            }
            if (value != null) {
                redisTemplate.opsForValue().set(key.toString(), value);
            }
        }
    
        @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("缓存出错 ");
            }
            return null;
        }
    
        @Override
        public Object removeObject(Object key) {
            if (redisTemplate == null) {
                //由于启动期间注入失败,只能运行期间注入,这段代码可以删除
                redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
            }
            if (key != null) {
                redisTemplate.delete(key.toString());
            }
            return null;
        }
    
        @Override
        public void clear() {
            log.debug("清空缓存");
            if (redisTemplate == null) {
                redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
            }
            Set<String> keys = redisTemplate.keys("*:" + this.id + "*");
            if (!CollectionUtils.isEmpty(keys)) {
                redisTemplate.delete(keys);
            }
        }
    
        @Override
        public int getSize() {
            if (redisTemplate == null) {
                //由于启动期间注入失败,只能运行期间注入,这段代码可以删除
                redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
            }
            Long size = redisTemplate.execute((RedisCallback<Long>) RedisServerCommands::dbSize);
            return size.intValue();
        }
    
        @Override
        public ReadWriteLock getReadWriteLock() {
            return this.readWriteLock;
        }
    }
    

    SpringUtil是手动获取bean的工具类

    @Component
    public class SpringUtil implements ApplicationContextAware {
    
        private static ApplicationContext applicationContext;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            SpringUtil.applicationContext = applicationContext;
        }
    
        public static Object getBean(String name){
            return applicationContext.getBean(name);
        }
    
        public static <T> T getBean(String name, Class<T> clazz){
            return applicationContext.getBean(name, clazz);
        }
    
        public static <T> T getBean(Class<T> clazz){
            return applicationContext.getBean(clazz);
        }
    }
    

    4. 在mapper上加上注解@CacheNamespace

    @CacheNamespace(implementation= MybatisRedisCache.class,eviction=MybatisRedisCache.class)
    public interface CommonMapper extends BaseMapper<Common> {
    

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

    file

  • 相关阅读:
    Linux下nginx 的常用命令
    Mybatis generator 自动生成代码(2)
    Android Retrofit2 网路编程
    Android webView输出自定义网页
    Android Studio OkHttpClient使用
    Android Studio SVN使用
    Android Toolbar的使用 顶部标题栏+后退键
    Android DrawLayout + ListView 的使用(一)
    RabbitMQ配置与安装
    Struts2拦截器
  • 原文地址:https://www.cnblogs.com/shuangyueliao/p/11504604.html
Copyright © 2020-2023  润新知