Spring Boot Redis 学习笔记(邮箱验证码)
Spring Boot Redis 学习笔记(邮箱验证码)
一、Redis 是什么?
可以把 Redis 理解成一个运行在服务器上的 HashMap。
Java 中:
HashMap<String, String> map = new HashMap<>();
map.put("name", "Tom");
String name = map.get("name");
Redis 中:
Key -> Value
name -> Tom
区别:
| HashMap | Redis |
|---|---|
| 存储在 Java 内存中 | 存储在 Redis 服务器中 |
| 程序关闭数据消失 | 可持久化保存 |
| 只能当前程序访问 | 多个程序均可访问 |
二、Spring Boot 如何操作 Redis?
Spring Boot 提供了 StringRedisTemplate,它相当于 Java 与 Redis 通信的工具对象。
@Autowired
private StringRedisTemplate stringRedisTemplate;
以后所有对 Redis 的操作,都通过它完成。
可以理解为:
Java代码
│
StringRedisTemplate
│
Redis服务器
三、Redis 存储验证码(重点)
1. 存储验证码
stringRedisTemplate.opsForValue().set(
"email:code:" + email,
code,
Duration.ofMinutes(5)
);
假设:
email = abc@qq.com
code = 483291
Redis 中最终保存:
Key:
email:code:abc@qq.com
Value:
483291
TTL:
300 秒
5 分钟后 Redis 自动删除该 Key。
2. 获取验证码
String code = stringRedisTemplate
.opsForValue()
.get("email:code:" + email);
返回:
- 验证码字符串
- 若返回
null,表示验证码不存在或已过期。
3. 删除验证码
验证码验证成功后立即删除:
stringRedisTemplate.delete(
"email:code:" + email
);
保证验证码只能使用一次。
四、邮箱验证码完整流程(重点)
用户点击发送验证码
│
▼
生成六位随机验证码
│
▼
发送 QQ 邮件
│
▼
Redis 保存
Key:
email:code:user@qq.com
Value:
483291
TTL:
5 分钟
│
▼
用户输入验证码
│
▼
Java 从 Redis 读取验证码
│
├── 不存在
│ ↓
│ 提示:验证码已过期
│
├── 不一致
│ ↓
│ 提示:验证码错误
│
└── 一致
│
▼
删除 Redis 中验证码
│
▼
注册成功
五、为什么 Key 要写成 email:code:abc@qq.com?
Redis 的 String 数据类型只能存:
一个 Key
↓
一个 Value
不能存在:
email
code
↓
483291
因此需要把邮箱作为 Key 的一部分。
推荐:
email:code:abc@qq.com
↓
483291
而不是:
code
↓
483291
否则多个用户会互相覆盖。
例如:
code
↓
483291
第二个人:
code
↓
725816
前一个验证码就没了。
为什么不用邮箱作为 Key?
例如:
abc@qq.com
↓
483291
技术上完全可以。
但是随着项目扩大:
abc@qq.com
↓
验证码
后来:
abc@qq.com
↓
用户对象
后来:
abc@qq.com
↓
Token
所有数据都会使用同一个 Key,彼此覆盖。
因此推荐增加业务前缀。
例如:
email:code:abc@qq.com
↓
483291
user:abc@qq.com
↓
用户对象
token:abc@qq.com
↓
JWT
这样不会发生 Key 冲突。
为什么喜欢使用冒号(:)?
Redis 对 Key 没有任何要求。
下面都合法:
email_code_abc@qq.com
email-code-abc@qq.com
verify#abc@qq.com
使用冒号只是 Redis 社区最常见的命名规范:
模块:功能:唯一标识
例如:
user:1
order:1001
email:code:abc@qq.com
方便阅读和管理。
六、TTL(Time To Live)
TTL(存活时间)表示 Key 多久后自动删除。
例如:
stringRedisTemplate.opsForValue().set(
"email:code:abc@qq.com",
"483291",
Duration.ofMinutes(5)
);
Redis:
email:code:abc@qq.com
↓
483291
TTL:
300 秒
随着时间递减:
300
299
298
...
1
0
时间到:
Redis 自动删除 Key
无需 Java 编写定时删除代码。
七、StringRedisTemplate 常用方法
保存
opsForValue().set(key, value);
保存(带 TTL)
opsForValue().set(key, value, Duration.ofMinutes(5));
查询
opsForValue().get(key);
删除
delete(key);
八、opsForValue() 是什么?
Redis 有多种数据类型。
opsForValue() 表示:
我要操作 Redis 的 String(字符串) 类型。
例如:
stringRedisTemplate
.opsForValue()
.set("name", "Tom");
等价于:
Key:
name
↓
Value:
Tom
九、Redis 常见数据类型(了解)
| Redis 数据类型 | Spring 方法 | 类似 Java |
|---|---|---|
| String | opsForValue() |
String |
| Hash | opsForHash() |
HashMap |
| List | opsForList() |
ArrayList / LinkedList |
| Set | opsForSet() |
HashSet |
| ZSet | opsForZSet() |
带排序的 Set |
目前邮箱验证码项目只需要掌握:
opsForValue()
即可。
其他数据结构可在实现用户缓存、排行榜等功能时再学习。
十、为什么需要 StringRedisTemplate?
StringRedisTemplate 是 Spring Boot 提供的 Redis 操作工具。
作用:
- 负责连接 Redis
- 发送 Redis 命令
- 接收 Redis 返回结果
可以理解为:
File
↓
操作文件
Connection
↓
操作数据库
StringRedisTemplate
↓
操作 Redis
十一、为什么需要序列化?(了解)
Redis 只能保存二进制数据,不认识 Java 对象。
因此:
Java对象
│
序列化
│
Redis
│
反序列化
│
Java对象
如果只存字符串(如验证码、Token),直接使用 StringRedisTemplate 即可,无需关心对象序列化。
只有需要直接存储 Java 对象(如 User、DTO、List、Map 等)时,才需要配置 RedisTemplate<String, Object> 并指定序列化方式。

浙公网安备 33010602011771号