zoukankan      html  css  js  c++  java
  • springboot整合redis——redisTemplate的使用

    一、概述

      相关redis的概述,参见Nosql章节

      redisTemplate的介绍,参考http://blog.csdn.net/ruby_one/article/details/79141940

      StringRedisTemplate作为RedisTemplate的子类,只支持KV为String的操作

    StringRedisTemplate与RedisTemplate
    两者的关系是StringRedisTemplate继承RedisTemplate。
    
    两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,
    RedisTemplate只能管理RedisTemplate中的数据。 SDR默认采用的序列化策略有两种,一种是String的序列化策略,一种是JDK的序列化策略。 StringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的。 RedisTemplate默认采用的是JDK的序列化策略,保存的key和value都是采用此策略序列化保存的。

      更多文档,参考javadoc:点击查看

      其他实战:参考码云springboot全家桶等!

    二、入门

      1.安装windows版redis

        由于windows的redis仅仅用于个人测试玩耍,这里就简单下载zip解压版本,相关配置项也不在这里赘述,参考linux下redis的介绍

        点击下载:https://github.com/MicrosoftArchive/redis/releases

          下载后解压;

         在解压所在目录使用如下命令启动服务端:(由于这里使用的win10的powershell,所以需要添加./,或者配置环境变量也可以避免使用./)

    ./redis-server.exe redis.windows.conf

        // 这里就不将其注册为windows服务了,关闭窗口,也就关闭了redis

        启动命令端:

    ./redis-cli.exe -h 127.0.0.1 -p 6379

      2.引入依赖

     <!-- springboot整合redis -->  
            <dependency>  
                <groupId>org.springframework.boot</groupId>  
                <artifactId>spring-boot-starter-data-redis</artifactId>  
            </dependency> 

      这里只需引入这一个redis的依赖即可,其他3个自动进行了依赖:

      

      3.在application.yml中配置redis

    #redis  
    spring.redis.hostName=127.0.0.1
    spring.redis.port=6379    
    spring.redis.pool.maxActive=8    
    spring.redis.pool.maxWait=-1    
    spring.redis.pool.maxIdle=8    
    spring.redis.pool.minIdle=0    
    spring.redis.timeout=0 

      // yml中改为yml的写法:

    # redis配置,以下有默认配置的也可以使用默认配置
      redis:
        host: 127.0.0.1
        port: 6379
        pool:
          max-active: 8
          max-wait: 1
          max-idle: 8
          min-idle: 0
        timeout: 0

      // 有许多的默认配置,可以直接使用默认

      如果换成了集群方式,配置修改入如下所示:

    spring:
        application:
            name: spring-boot-redis
        redis:
            host: 192.168.145.132
            port: 6379
            timeout: 20000
            cluster:
                nodes: 192.168.211.134:7000,192.168.211.134:7001,192.168.211.134:7002
                maxRedirects: 6
            pool:
                max-active: 8
                min-idle: 0
                max-idle: 8
                max-wait: -1

      // 对应的配置类:org.springframework.boot.autoconfigure.data.redis.RedisProperties

      4.建立redis配置类

    package com.example.demo.config;
    
    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    /**
     * redis配置类
     *
     * @author zcc ON 2018/3/19
     **/
    @Configuration
    @EnableCaching//开启注解
    public class RedisConfig {
        @Bean
        public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
            CacheManager cacheManager = new RedisCacheManager(redisTemplate);
            return cacheManager;
            /*RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
            // 多个缓存的名称,目前只定义了一个
            rcm.setCacheNames(Arrays.asList("thisredis"));
            //设置缓存默认过期时间(秒)
            rcm.setDefaultExpiration(600);
            return rcm;*/
        }
        // 以下两种redisTemplate自由根据场景选择
        @Bean
        public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
            RedisTemplate<Object, Object> template = new RedisTemplate<>();
            template.setConnectionFactory(connectionFactory);
    
            //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
            Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
    
            ObjectMapper mapper = new ObjectMapper();
            mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
            mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
            serializer.setObjectMapper(mapper);
    
            template.setValueSerializer(serializer);
            //使用StringRedisSerializer来序列化和反序列化redis的key值
            template.setKeySerializer(new StringRedisSerializer());
            template.afterPropertiesSet();
            return template;
        }
        @Bean
        public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
            StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
            stringRedisTemplate.setConnectionFactory(factory);
            return stringRedisTemplate;
        }
    }

      5.编写相关的实体类

        这里注意一定要实现序列化接口用于序列化!

    public class Girl implements Serializable{
    
        private static final long serialVersionUID = -3946734305303957850L;

      // IDEA开启Java的检查即可自动生成!

      6.相关的service

        处理缓存相关的前缀的常量类:

    public class RedisKeyPrefix {
        private RedisKeyPrefix() {
        }
    
        public static final String GIRL = "girl:";
    
    }
      /**
         * 通过id查询,如果查询到则进行缓存
         * @param id 实体类id
         * @return 查询到的实现类
         */
        public Girl findOne(Integer id) {
            String key = RedisKeyPrefix.GIRL + id;
            // 缓存存在
            boolean hasKey = redisTemplate.hasKey(key);
            if (hasKey) { // 从缓存中取
                Girl girl = redisTemplate.opsForValue().get(key);
                log.info("从缓存中获取了用户!");
                return girl;
            }
            // 从数据库取,并存回缓存
            Girl girl = girlRepository.findOne(id);
            // 放入缓存,并设置缓存时间
            redisTemplate.opsForValue().set(key, girl, 600, TimeUnit.SECONDS);
            return girl;
        }

      特别注意的是这里的注入,由于之前配置了redisTemplate及其子类,故需要使用@Resource注解进行!

    @Resource
        private RedisTemplate<String, Girl> redisTemplate;
        // private RedisTemplate<String, Object> redisTemplate;根据实际情况取泛型

      剩下的删除和更新也是对应的操作缓存,参考网友的写法:

    /**
         * 更新用户
         * 如果缓存存在,删除
         * 如果缓存不存在,不操作
         *
         * @param user 用户
         */
        public void updateUser(User user) {
            logger.info("更新用户start...");
            userMapper.updateById(user);
            int userId = user.getId();
            // 缓存存在,删除缓存
            String key = "user_" + userId;
            boolean hasKey = redisTemplate.hasKey(key);
            if (hasKey) {
                redisTemplate.delete(key);
                logger.info("更新用户时候,从缓存中删除用户 >> " + userId);
            }
        }
    
        /**
         * 删除用户
         * 如果缓存中存在,删除
         */
        public void deleteById(int id) {
            logger.info("删除用户start...");
            userMapper.deleteById(id);
    
            // 缓存存在,删除缓存
            String key = "user_" + id;
            boolean hasKey = redisTemplate.hasKey(key);
            if (hasKey) {
                redisTemplate.delete(key);
                logger.info("删除用户时候,从缓存中删除用户 >> " + id);
            }
        }

      更多基本用法,参考http://blog.csdn.net/ruby_one/article/details/79141940

    三、注意事项与相关问题

      1.数据同步问题

    redis和mysql数据的同步,代码级别大致可以这样做:
    读: 读redis->没有,读mysql->把mysql数据写回redis
    写: 写mysql->成功,写redis

      2.统一管理key 前缀

        通过常量类的形式(阿里的解决方案),当然,通过配置properties 等也是阔以的

      3.开发规范

        参考nosql 入门章节介绍

  • 相关阅读:
    OutputCache 缓存key的创建 CreateOutputCachedItemKey
    Asp.net Web Api源码调试
    asp.net mvc源码分析DefaultModelBinder 自定义的普通数据类型的绑定和验证
    Asp.net web Api源码分析HttpParameterBinding
    Asp.net web Api源码分析HttpRequestMessage的创建
    asp.net mvc源码分析ActionResult篇 RazorView.RenderView
    Asp.Net MVC 项目预编译 View
    Asp.net Web.config文件读取路径你真的清楚吗?
    asp.net 动态创建TextBox控件 如何加载状态信息
    asp.net mvc源码分析BeginForm方法 和ClientValidationEnabled 属性
  • 原文地址:https://www.cnblogs.com/jiangbei/p/8601107.html
Copyright © 2011-2022 走看看