Springboot整合Redis

准备工作

  • 如果Redis是在远程或者在linux虚拟机中,需要先关闭防火墙,或者将Redis服务运行的端口打开(任意选择一种方式即可)

    • 方法1. 关闭防火墙 (CentOS中)

      #直接关闭防火墙
      [root@localhost bin]# systemctl stop firewalld
      
    • 方法2. 打开Redis服务端口,假如我Redis的端口是6379

      [root@localhost redisconf]# firewall-cmd --zone=public --add-port=6379/tcp --permanent
      success
      
      #重新加载
      [root@localhost redisconf]# firewall-cmd --reload
      success
      #查看所有开放的端口
      [root@localhost redisconf]# firewall-cmd --permanent --zone=public --list-ports
      6379/tcp
      
      #读取配置文件启动Redis服务
      [root@localhost bin]# /redis-server redisconf/redis.conf
      
  • 需要关闭Redis的保护模式,如果开启了该模式,则只有本机能连接该Redis,其他外部的IP是无法连接的,在redis.conf中修改

    vEM039.png

  • 如果Redis是在远程或者在linux虚拟机中,需要先启动Redis服务,也就是执行redis-server redis.conf

整合Redis

步骤:

  1. 添加Redis依赖

springboot已经将对Redis的操作已经封装成一个类了,我们需要在springboot引入一个Redis依赖,该依赖中底层连接Redis的方法现在不是使用的 Jedis,而是使用的lettuce,因为lettuce是线程安全的,而Jedis是线程不安全的

<!--引入Redis的依赖-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

在添加完这个依赖之后,spring Boot就会帮我们创建两个对象并放到了Spring容器中,叫做:RedisTemplateStringRedisTemplate ,这两个对象就是我们在springboot中操作Redis需要使用的。

注意:RedisTemplate对象可以用来操作Redis中任意数据类型,比如String,List,Set,Zset,Hash等,而StringRedisTemplate只能操作String类型

  1. 在SpringBoot的配置文件application.yaml中配置Redis的连接信息,比如ip,启动端口号,密码,数据库等
#配置redis需要指定 host,ip,password
spring:
  redis:
    host: 192.168.226.128  #ip地址
    port: 6381    #启动端口号,默认是6379端口
    password: orange  #Redis密码,也就是在redis.conf中requirepass中配置的
    database: 0  #使用的Redis数据库的下标,默认是第一个,下标为0
  1. 测试连接Redis,使用redisTemplate 或 stringRedisTemplate对象来操作

    – 对于redisTemplate对象中的方法:

    vQCTNF.png

    解释:opsForSet :表示是对Redis中Set类型的操作 ,返回一个SetOperations对象,该对象中包括所有对Set类型的操作方法

    opsForValue :表示是对Redis中String类型的操作 ,返回一个ValueOperations对象,该对象中包括所有对String类型的操作方法

    opsForHash :表示是对Redis中Hash类型的操作 ,返回一个SetOperations对象,该对象中包括所有对Hash类型的操作方法

    opsForZSet :表示是对Redis中ZSet类型的操作 ,返回一个SetOperations对象,该对象中包括所有对ZSet类型的操作方法

    opsForList :表示是对Redis中List类型的操作 ,返回一个SetOperations对象,该对象中包括所有对List类型的操作方法

    依此类推 …

    除了这些还包括对Redis的简单操作

    redisTemplate.keys("*")  //查看所有的key
    redisTemplate.delete()   //删除某些key
    redisTemplate.multi()    //开启事务
    redisTemplate.exec()    //执行事务
    redisTemplate.discard() //停止(中断)事务
       ...
    

    – 对于stringRedisTemplate对象中的方法 和 redisTemplate类似:

    opsForValue :表示是对Redis中String类型的操作 ,返回一个ValueOperations**<String , String>**对象,该对象中包括所有对String类型的操作方法 ,同样还包括对Redis的简单操作

    测试代码

    @SpringBootTest
    class SpringBootRedis05ApplicationTests {
        //直接将这两个对象注入,因为已经在spring容器中了,默认名字就是redisTemplate和stringRedisTemplate
        @Resource
        private RedisTemplate redisTemplate;
    
        @Resource
        private StringRedisTemplate stringRedisTemplate;
    
        @Test
        public void testRedis(){
          //使用RedisTemplate添加一个String类型数据到Redis数据库
            redisTemplate.opsForValue().set("testRedisTemplate","Hello,RedisTemplate");
            
          //使用StringRedisTemplate添加一个String类型数据到Redis数据库
            stringRedisTemplate.opsForValue().set("testStringRedisTemplate","Hello,StringRedisTemplate");
            
          //分别获取添加的数据
            System.out.println(redisTemplate.opsForValue().get("testRedisTemplate"));
            System.out.println(stringRedisTemplate.opsForValue().get("testRedisTemplate"));
        }
    }
    
    

输出结果:(连接成功,并且能正常存取值到Redis中)

vQEN9S.png

在Redis中查看数据

发现问题:使用RedisTemplate对象存入的数据键值对都是显示乱码的,而使用StrringRedisTemplate对象存入的数据键值对都是显示正常的

vQVMCT.png

解释乱码原因

  • 因为任何数据存入到Redis中都是需要先经过序列化的,然后将序列化之后的数据存入,之所以会造成RedisTemaplate对象数据显示乱码,而StringRedisTemaplate对象数据显示正常,根本原因:它们俩默认的 序列化方式不同

  • 测试获取默认的序列化方式(包括对key和value的序列化方式

@SpringBootTest
class SpringBootRedis05ApplicationTests {
    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Test
    public void testRedis(){
        
      // redisTemplate.getConnectionFactory().getConnection().flushDb();
        System.out.println("查看stringRedisTemplate的默认序列化方式");
        System.out.println(stringRedisTemplate.getDefaultSerializer());
        System.out.println(stringRedisTemplate.getKeySerializer());
        System.out.println(stringRedisTemplate.getValueSerializer());
        
        
        System.out.println("查看RedisTemplate的默认序列化方式");
        System.out.println(redisTemplate.getDefaultSerializer());
        System.out.println(redisTemplate.getKeySerializer());
        System.out.println(redisTemplate.getValueSerializer());

    }
}

输出结果:可以看出,这两个对象默认的序列化方式都是jdk的序列化,但是RedisTemplate对于key和value的序列化方式仍然使用jdk的序列化方式,而StringRedisTemplate对于key和value的序列化方式是字符串的序列化

vQeWjg.png

jdk序列化:是将数据变成字节数组后传输,且jdk序列化是不支持跨平台和语言的,也就是先将key和value转换成字节数组后再存到Redis中的,所以显示的不是我们想看的。

解决办法

  • 我们一般使用的序列化都是将key使用string的序列化,而value就是使用json的序列化,将value转换成一个json格式的字符串进行保存

  • 如何修改默认RedisTemplate 的序列化配置?

    源码分析:

在Redis的自动装配类RedisAutoConfiguration中创建了RedisTemplate对象,并注入到Spring容器的

@AutoConfiguration
@ConditionalOnClass({RedisOperations.class})
@EnableConfigurationProperties({RedisProperties.class})
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
    public RedisAutoConfiguration() {
    }

    //使用@Bean注解将方法返回值注入到spring容器,默认注入的是 RedisTemplate<Object, Object> 对象
    @Bean
    @ConditionalOnMissingBean(
        name = {"redisTemplate"}
    )
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        return new StringRedisTemplate(redisConnectionFactory);
    }
}

vQl1x0.png

也就是说,如果存在一个bean叫做redisTemplate的时候,就不会调用这个方法,也就是该类不会再创建一个redisTemplate对象,所以我们可以自己创建一个叫做redisTemplate的对象,然后修改它的序列化方式,这样就使用我们自己创建的redisTemplate对象来进行对Redis的操作

总结一句话:创建自己的redisTemplate对象来覆盖springboot帮我们创建的,我们自己创建就可以指定序列化方式了

  • 自己创建的配置类:

    package com.example.config;
    
    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.RedisSerializer;
    
    import java.net.UnknownHostException;
    
    //加上@Configuration表示该类是一个配置类
    @Configuration
    public class RedisConfig {
    
        //自己创建RedisTemplate对象并放到spring容器中去
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
            // 将redisTemplate 泛型设置为 <String, Object>
            RedisTemplate<String, Object> template = new RedisTemplate();
            // 连接工厂,不必修改
            template.setConnectionFactory(redisConnectionFactory);
            /*
             * 序列化设置
             */
            //redisTemplate 中的 key、hash的key 采用 String序列化方式
            template.setKeySerializer(RedisSerializer.string());
            template.setHashKeySerializer(RedisSerializer.string());
    
            //redisTemplate 中的 value、hash的value 采用 Jackson 序列化方式
            template.setValueSerializer(RedisSerializer.json());
            template.setHashValueSerializer(RedisSerializer.json());
            template.afterPropertiesSet();
    
            return template;
        }
    
    }
    
    
  • 运行测试程序

vQ8NdS.png

  • 运行结果

    vQEN9S.png

  • 在Redis客户端中查看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值