• SpringBoot整合redis


    一、SpringBoot整合

    SpringBoot 操作数据:spring-data jpa jdbc mongodb redis!
    SpringData 也是和 SpringBoot 齐名的项目!

    说明: 在 SpringBoot2.x 之后,原来使用的jedis 被替换为了 lettuce?
    jedis : 采用直连,多个线程操作的话,是不安全的,如果想要避免不安全的,使用 jedis pool 连接
    池! 更像 BIO 模式
    lettuce : 采用netty,实例可以在多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据
    了,更像 NIO 模式

    二、RedisAutoConfiguration自动配置类

    自动配置类springboot已经帮我们写好,来看看源码
    源码分析,下面是springboot中 RedisAutoConfiguration自动配置类 的源码中的方法

    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate") // 我们可以自己定义一个
    redisTemplate来替换这个默认的!
    public RedisTemplate<Object, Object>redisTemplate(RedisConnectionFactory redisConnectionFactory)throws UnknownHostException {
        // 默认的 RedisTemplate 没有过多的设置,redis 对象都是需要序列化!
        // 两个泛型都是 Object, Object 的类型,我们后使用需要强制转换 
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
    @Bean
    @ConditionalOnMissingBean // 由于 String 是redis中最常使用的类型,所以说单独提出来了一
    个bean!
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)throws UnknownHostException {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    1、整合测试一下

    1. 导入springboot-redis的 依赖
    
    <dependency>
      <groupId>org.springframework.bootgroupId>
      <artifactId>spring-boot-starter-data-redisartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 配置连接,在application.properties中
    # 配置redis
    spring.redis.host=127.0.0.1
    spring.redis.port=6379
    
    • 1
    • 2
    • 3
    1. 测试!在测试类中自动装配RedisTemplate(因为springboot已经通过RedisAutoConfiguration配置类帮我们注入了RedisTemplate),然后通过RedisTemplate 去操作 Redis
    @SpringBootTest
    class Redis02SpringbootApplicationTests {
        @Autowired
        private RedisTemplate redisTemplate;
        @Test
        void contextLoads() {
            // redisTemplate 操作不同的数据类型,api和我们的指令是一样的
            // opsForValue 操作字符串 类似String
            // opsForList 操作List 类似List
            // opsForSet
            // opsForHash
            // opsForZSet
            // opsForGeo
            // opsForHyperLogLog
            // 除了进本的操作,我们常用的方法都可以直接通过redisTemplate操作,比如事务,和基本的 CRUD
            // 获取redis的连接对象
            // RedisConnection connection =
            redisTemplate.getConnectionFactory().getConnection();
            // connection.flushDb();
            // connection.flushAll();
            redisTemplate.opsForValue().set("mykey","关注狂神说公众号");
            System.out.println(redisTemplate.opsForValue().get("mykey"));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述
    关于对象的保存:

    对象没有序列化传输保存会报错

    在这里插入图片描述

    序列化对象,才能在redis的value中正常保存并获取对象

    public class User implements Serializable {
        private String name;
        private int age;
    }
    
    • 1
    • 2
    • 3
    • 4

    三、自定义RedisTemplete

    默认序列化是jdk的序列化方式,自定义RedisTemplete配置config可以自定义序列化方式
    可以自己配置具体的序列化方式,代码如下所示我们来编写一个自己的 RedisTemplete(下面是一个固定的模板,可以直接用)

    自己写一个配置类,注入自己定义的RedisTemplate

    package com.kuang.config;
    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    @Configuration
    public class RedisConfig {
        // 这是我给大家写好的一个固定模板,大家在企业中,拿去就可以直接使用!
        // 自己定义了一个 RedisTemplate
        @Bean
        @SuppressWarnings("all")
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
            // 我们为了自己开发方便,一般直接使用 
            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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    所有的redis操作,其实对于java开发人员来说,十分的简单,更重要是要去理解redis的思想和每一种数据结构的用处和作用场景!

    1、在测试test中使用自定义的RedisTemplete

    首先自动装配,因为在配置类中注入过了

    在这里插入图片描述

    装配时要选择自定义的RedisTemplate而不是源码中的

    在这里插入图片描述

    2、自定义RedisTemplete后测试

        //保存对象到redis
        @Test
        public void test() throws JsonProcessingException {
            User user = new User("hhb", 20);
    
            //String jsonUser = new ObjectMapper().writeValueAsString(user);  //转换为json字符串
            redisTemplate.opsForValue().set("user",user);
            System.out.println(redisTemplate.opsForValue().get("user"));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果

    因为key 已经采用 String序列化方式
    在这里插入图片描述

    自定义RedisTemplate并为其设置序列化方式之前,key是乱码

    在这里插入图片描述

    四、在企业开发中,大部分情况下都不会使用原生方式编写redis

    不会像下面这样
    在这里插入图片描述

    1、编写RedisUtils代替原生(操作RedisTemplate)的方式

    在真实开发中,或者公司,一般都会看到一个封装的 RedisUtil工具类文件(在文章标题处给出RedisUtil工具类附件),因为文件代码太长所以提供文件附件(百度csdn中应该也有很多容易搜到)

    示例部分代码如下,都是封装了一些redis的操作,把redis的操作封装为了RedisUtils的方法。

    @Component
    @SuppressWarnings({"unchecked", "all"})
    public class RedisUtils {
        private static final Logger log = LoggerFactory.getLogger(RedisUtils.class);
        private RedisTemplate<Object, Object> redisTemplate;
        // @Value("${jwt.online-key}")
        // private String onlineKey;
    
        public RedisUtils(RedisTemplate<Object, Object> redisTemplate) {
            this.redisTemplate = redisTemplate;
            this.redisTemplate.setHashKeySerializer(new StringRedisSerializer());
            this.redisTemplate.setKeySerializer(new StringRedisSerializer());
            this.redisTemplate.setStringSerializer(new StringRedisSerializer());
        }
    
        /**
         * 指定缓存失效时间
         *
         * @param key  键
         * @param time 时间(秒)
         */
        public boolean expire(String key, long time) {
            try {
                if (time > 0) {
                    redisTemplate.expire(key, time, TimeUnit.SECONDS);
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return false;
            }
            return true;
        }
    
        /**
         * 指定缓存失效时间
         *
         * @param key      键
         * @param time     时间(秒)
         * @param timeUnit 单位
         */
        public boolean expire(String key, long time, TimeUnit timeUnit) {
            try {
                if (time > 0) {
                    redisTemplate.expire(key, time, timeUnit);
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return false;
            }
            return true;
        }
    
        /**
         * 根据 key 获取过期时间
         *
         * @param key 键 不能为null
         * @return 时间(秒) 返回0代表为永久有效
         */
        public long getExpire(Object key) {
            return redisTemplate.getExpire(key, TimeUnit.SECONDS);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    2、测试,使用redisUtils操作redis

    因为RedisUtils被注册成了组件,所以可以Autowired自动装配
    在这里插入图片描述
    输出结果如下
    在这里插入图片描述

  • 相关阅读:
    STFT:解决音频-视频零样本学习 (ZSL) 中的挑战
    基于Java实现的词法分析器
    QMainWindow的使用
    (蓝桥杯C/C++)—— 编程基础
    抄写Linux源码(Day16:内存管理)
    语义SLAM论文以及code地址总结
    Tomcat7+ Weak Password && Backend Getshell Vulnerability
    树莓派入门
    UDS安全访问之27服务SecurityAccess
    查看电脑的 CPU 信息
  • 原文地址:https://blog.csdn.net/hhb442/article/details/133558773