基于 Spring 的 Redis 操作⼿册
⼀、概述
为了解决数据库的性能瓶颈,甚⾄为了解决两端的耦合性,通常我们会接⼊第三⽅平台来解决此问题,我们⼀般将其称作为 中间件 。我们将基于硬盘的数据库总的数据迁移到基于内存的数据库中,该数据库我们称作 缓存中间件 即我们的 Redis 。由于 Redis 使⽤ C语⾔ 开发,为便于 Redis 的操作,Spring团队 将其⼆次封装并简化其操作且命名为 RedisTemplate ⼯具类。
redisTemplate.opsForValue().setIfAbsent(“key-3”, “value123”, 10, TimeUnit.SECONDS);
⼆、Redis 的部署
2.1. Redis 的拉取
⼀般的,我们通过使⽤ Docker 容器来部署我们的 Redis服务 ,为了⽅便我们学习阶段的使⽤,我们暂不做 Redis 持久化操作 。我们将在后续引⼊。我们通过基于 Debian 的 Linux 发⾏版中的 Docker 来构建 Redis ,终端指令如下所⽰:
$ sudo docker pull redis
注意: 我们反复强调说,如果您的 Linux 帐号为⾮ root 账⼾,那么就必须加 sudo 提权,如果是root 帐号,则不需要加 sudo !
2.2. Redis 的初始化
同样的,我们说我们不需要将 Redis 做 持久化 的操作,所以我们仅需要⽆配置⽂件化的启动即可,我们在终端键⼊如下指令:
// 这⾥我们的 -p 端口,我们说 冒号 左边都是对应的物理机,冒号 右边都是对应的 Docker 容器,端口
不需要相同
$ sudo docker run -it --name redis -p 36379:6379 -d redis
初始化操作完成后,我们通过如下指令查看是否真正的完成了 Redis 的初始化:
$ sudo docker ps
// 随后我们应该能看到类似如下信息
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
69b4984493e8 redis "docker-en" 47 minutes ago Up 47 minutes 0.0.0.0:36379-
>6379/tcp, :::36379->6379/tcp redis
三、项⽬中的配置
3.1. 依赖的引⼊
在我们的 spring boot 或者 spring cloud 项⽬中,我们通过引⼊如下依赖完成对 Redis 的引⼊:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
3.2. Redis 的配置
引⼊依赖后,我们在 application.yml 配置⽂件中配置如下配置选项:
// 注意,redis 的配置项是在 spring 的⼆级树形下
redis:
// Redis 的连接地址
host: localhost
# Redis 的端口
port: 36379
// Redis 的密码,这⾥我们暂时没有设置密码
password: ''
// Redis 中使⽤哪个分区,使⽤哪个库,默认有16个,任取⼀个即可
database: 1
// 使⽤ Lettuce 作为连接池
lettuce:
pool:
// Redis 的最⼤连接数
max-active: 1000
// Redis 最⼤空闲数
max-idle: 10
// Redis 最小空闲数
min-idle: 3
// 空闲的连接不被清除,时间⽆限等待连接直到超时
max-wait: -1
整个 application.yml 的配置如下所⽰,这⾥放出整个配置的⽬的是为了说明 Redis 的配置位于
Spring 配置层级的第⼆层,是 属于Spring 的。
spring:
application:
name: spring-practice
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:63306/test_db
username: test_user
password: '123456789'
type: com.zaxxer.hikari.HikariDataSource
hikari:
max-lifetime: 2000000
maximum-pool-size: 20
// 这⾥是 Redis 的配置,位于 Spring 的第⼆层级,它是属于 Spring 的
redis:
host: localhost
port: 36379
password: ''
database: 1
lettuce:
pool:
max-wait: -1
max-active: 1000
max-idle: 10
min-idle: 3
server:
port: 30000
mybatis:
mapper-locations: classpath:mapper/**.xml
3.3. 配置 RedisTemplate
Spring 团队封装的⼯具类是⽐较喜欢使⽤ xxTemplate 作为命名。既然我们要使⽤RedisTemplate ,那么我们也要和 RestTemplate ⼀样也独⽴配置⼀下 RdisTemplate 的⼯具⽅法。
3.3.1. 序列化的配置
我们键⼊如下⽅法来配置 RedisTemplate :
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory
lettuceConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>
(Object.class));
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>
(Object.class));
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
return redisTemplate;
}
其中主要 序列化 和 反序列化 了普通字符操作和HASH操作,并以 Lettuce 作为连接池完成初始
化。
3.3.2.springframework ⼯具类的启动加载
我们在⼯具类上仅仅需要添加 @Configuration 注解即可完成该类的初始化加载,在⽅法上⾯仅
仅需要添加 @Bean 即可完成⽅法⼯具的加载。
3.3.3. 完整⼯具类配置代码
完整的⼯具类配置代码如下代码所⽰:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @author zhang
* <p>
* 基于 Lettuce 的 Redis 的 Spring 的 RedisTemplate 的配置
*/
@Configuration
public class RedisConfig {
/**
* 具体配置 RedisTemplate ⼯具类
*
* @param lettuceConnectionFactory lettuce 连接⽅式
* @return {@link RedisTemplate}
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory
lettuceConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
return redisTemplate;
}
}
四、Redis 及 RedisTemplate 的使⽤
我们使⽤ Spring 封装的 RedisTemplate 来完成对 Redis 的操作。
4.1. 数据的简单存储
常规的字符存储我们通过如下代码即可完成:
// 通过 set ⽅法直接将数据写⼊数据
redisTemplate.opsForValue().set("key-1", id);
4.2. 数据的获取
// 通过 get ⽅法获取 key 并拿到 Value
redisTemplate.opsForValue().get("key-1");
通过如下代码可直接获取
4.3. 数据的删除
通过如下代码直接删除
// 通过 delete ⽅法删除数据
redisTemplate.delete("key-1");
4.4. List 数据的写⼊
通过如下代码直接写⼊ List 类型数据
List<String> list = new ArrayList<>();
list.add("A数据");
list.add("B数据");
list.add("C数据");
// 通过 leftPush 写⼊ key, value 数据
redisTemplate.opsForList().leftPush("list", list);
4.5. List数据的读取
// 通过 rightPop ⽅法可直接获取 List 类型的数据
redisTemplate.opsForList().rightPop("list");
4.6. Map 数据的写⼊
通过如下代码可直接写⼊ Map 类型的数据
Map<String, Object> map = new HashMap<>(4);
map.put("A", "Map A");
map.put("B", "Map B");
map.put("C", "Map C");
// 通过 putAll ⽅法写⼊ key value 的 map 数据
redisTemplate.opsForHash().putAll("map", map);
4.7. Map 数据的读取
Map 数据的读取有两种⽅式,⼀种是直接读取 List 类型的 Map数据,第⼆种是读取 Map 键值对的数据。
4.7.1. 获取 List 类型的 Map 数据
通过如下代码可直接获取 List 类型的 Map 数据:
// 通过 values ⽅法可直接获取 List 类型的 Map 数据
redisTemplate.opsForHash().values("map");
4.7.2. 获取 Map 键值对类型的 Map 数据
通过如下代码可直接获取 Map 键值对类型的数据
// 通过 entries ⽅法可直接获取 键值对 的 Map 数据
redisTemplate.opsForHash().entries("map");
4.8. 过期⾃动删除数据
通过如下代码可在规定过期后⾃动删除 Redis 中的数据:
// 其中 key, value, 时间,单位 4个参数
redisTemplate.opsForValue().setIfAbsent("key-3", "value123", 10,
TimeUnit.SECONDS);