Redis的简单使用

本节主要是介绍 spring-boot-starter-data-redis,如何在项目中简单地使用 Redis。不过这里还是使用创建 Redis 工厂的方式来获取连接,方式有点过时,但重在了解。

Spring-boot-starter-data-redis介绍

在 Spring 中想要使用 Redis,则需要加入 Redis 的依赖。在 Spring Boot 中将 Redis 封装成 starter,只需要使用配置,就可以方便地操作 Redis。因此,这里只需要加入简单的依赖如下。

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

这时,就可以通过 Java 对 Redis 进行操作。

Redis的使用

在开始程序编写之前,为了重现程序,还是展示一下程序结构,如图8.1所示。在 Redis 的使用这一节,将会新建一个包的实例程序。

image 2024 03 31 22 02 59 966
Figure 1. 图8.1 程序结构

首先,在 Spring Boot 1.x 中,还是使用 JedisConnectionFactory 进行连接,因此代码如下所示。

package com.springBoot.redis.config;
@Configuration
public class RedisConfig {
   @Bean
   public RedisConnectionFactory getFactory(){
      JedisConnectionFactory factory=new JedisConnectionFactory();
      factory.setPort(6379);
      factory.setHostName("127.0.0.1");
      return factory;
   }
}

在上面的代码中,通过配置类创建 Redis 工厂,方便生成 Redis 数据库的连接。现在我们继续使用 SET 的方法,设置端口、主机。虽然 setPort、setHostName 方法都不再推荐使用,因为不推荐直接连接的方式,不过这种方式依旧可以使用,也可以了解一下曾经的使用方式,后面会进行改造。然后,写测试类程序进行测试,代码如下所示。

package com.springBoot.redis;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Application.class)
public class RedisApplicationTest {
   @Autowired
   RedisConnectionFactory redisConnectionFactory;
   @Test
   public void testRedis(){
      RedisConnection connection=redisConnectionFactory.getConnection();
      connection.set("myKey".getBytes(),"myValue".getBytes());
        System.out.println("myKey:"+new String(connection.get("myKey".getBytes())));
   }
}

上面的代码分为三个部分,通过工厂获取 Redis 的连接,然后 SET 数据到 Redis,最后再将数据从 Redis 中取出来。需要注意的是我们在操作时都使用 byte 数组类型,操作起来不方便,后续在8.2.2节学习使用 template,会更加方便。最后,看看执行结果,如图8.2所示。

image 2024 03 31 22 05 24 853
Figure 2. 图8.2 执行结果

那么 Redis 中的结果是什么样?这里的 Redis 安装在 Microsoft Windows 本地,进入命令行,查看结果如图8.3所示。

image 2024 03 31 22 06 05 551
Figure 3. 图8.3 Redis数据存储

使用配置类建立Redis工厂

在将 spring-boot-starter-data-redis 依赖引入之后,就自然地引入异步客户端 Lettuce。在一般的项目中,我们使用的是 Redis,用于 SSL 连接以及连接池的使用,因此下面是配置类与统一的客户端 Redis 的使用方法。首先,在开始前,需要修改 pom 文件,依赖如下所示。

<!--Redis-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-redis</artifactId>
   <exclusions>
      <exclusion>
          <groupId>io.lettuce</groupId>
          <artifactId>lettuce-core</artifactId>
      </exclusion>
   </exclusions>
</dependency>
<!--Redis client-->
<dependency>
   <groupId>redis.clients</groupId>
   <artifactId>jedis</artifactId>
   <version>2.9.0</version>
</dependency>

在上面的依赖中,我们需要排除 Lettuce,然后引入 Redis 客户端。

不使用连接池

上面的使用连接信息直接连接的方式已经不再推荐,但工厂类还支持,因此可以使用配置类。目前主要有三种配置类,即 standlone、sentinel、redisCluster。

package com.springBoot.redis.config;

@Configuration
public class RedisConfig {
   @Bean
   public JedisConnectionFactory getFactory(){
      RedisStandaloneConfiguration redisStandaloneConfiguration=new
RedisStandaloneConfiguration();
      redisStandaloneConfiguration.setDatabase(0);
      redisStandaloneConfiguration.setHostName("127.0.0.1");
      redisStandaloneConfiguration.setPort(6379);
      redisStandaloneConfiguration.setPassword(RedisPassword. of("123456"));
      JedisConnectionFactory factory = new JedisConnectionFactory (redisStandaloneConfiguration);
      return factory;
   }
}

在上面的代码中,使用的是 RedisStandloneConfiguration 配置类,使用这个配置类来初始化 Redis 工厂。具体如何使用工厂类,在后面介绍模板 template 时,会进行讲解。

使用连接池

其实上面的方式不是很好,因为每次都会新建一个连接,然后使用命令对 Redis 进行操作,在高并发时,将会特别消耗资源,使系统性能下降。在 Redis 中,可以采取批量处理的方式,但是在这里,为了和上面的代码进行匹配,我们可以使用连接池的方式,代码如下所示。

@Bean
public JedisPoolConfig jedisPoolConfig() {
   JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
   jedisPoolConfig.setMaxTotal(50);
   jedisPoolConfig.setMinIdle(10);
   jedisPoolConfig.setMaxWaitMillis(50000);
   return jedisPoolConfig;
}

为了节约篇幅,上面的代码没有放在类中,这个 @Bean 可以放在前面的 RedisConfig 中。说明上面的代码,我们先对连接池的属性进行说明。

  • MaxTotal:最大连接数,默认为 8。

  • Minldle:最小空闲数,默认为 0。

  • MaxIdle:最大空闲数,默认为 8。

  • MaxWaitMillis:在获取连接时的最大等待毫秒数,默认为 -1,如果超时则抛出异常。

  • BlockWhenExhausted:连接耗尽的时候是否阻塞,值为 true 则阻塞,但超时了会报异常;值为 false 则直接报异常。默认为 true。

  • JmxEnabled:是否启用 pool 的 JMX 功能,默认为 true。

  • Lifo:是否启用后进先出模式,默认为 true。

  • TestOnBorrow:在获取连接时检查有效性,默认为 false。