redis是缓存,算是另一种数据库(键值对key-value),一般数据都是存在mysql这种数据库里面,是存在磁盘里面,redis是存在内存里面。
Redis数据类型
1. String(字符串)—— 最简单的“标签纸”
这是最基础的类型,一个 Key 对应一个 Value。
- 通俗理解:就像在储物柜贴一张标签纸,上面写个名字或数字。
- 怎么用:直接存、直接取。
- 生活场景:
-
- 验证码:手机号是 Key,验证码是 Value,设置 5 分钟后过期。
- 计数器:记录这篇文章有多少人点赞(
INCR命令直接加 1)。
2. Hash(哈希)—— 一个“小档案袋”
如果你想存一个人的姓名、年龄、职业,用 String 存一堆 Key 太乱了,Hash 就像个档案袋。
- 通俗理解:抽屉里放了一个文件夹,里面有一张表,分成了很多行(Field)和值(Value)。
- 怎么用:存对象,可以只修改对象里的某一个属性。
- 生活场景:
-
- 用户信息:
User:1001这个文件夹里,存着name: 张三,age: 20,city: 重庆。
- 用户信息:
3. List(列表)—— 一队“排队的人”
它是一个双向链表,数据是有先后顺序的,且可以重复。
- 通俗理解:像食堂排队,你可以从队头(左边)插进去,也可以从队尾(右边)排进去。
- 怎么用:适合存需要显示“先后顺序”的数据。
- 生活场景:
-
- 消息列表:比如朋友圈动态,最新的动态永远排在最上面。
- 简单队列:先把任务存进去,后台程序按顺序一个一个取出来处理。
4. Set(集合)—— 一个“抽奖箱”
它是一堆乱序的、绝对不重复的数据。
- 通俗理解:往盒子里扔小球,哪怕你扔两个一模一样的,盒子里也只会剩下一个。它还能帮你做“交集”、“差集”。
- 怎么用:去重、找共同点。
- 生活场景:
-
- 共同好友:你是 A 集合,我是 B 集合,求个交集就知道咱们共同认识谁了。
- 抽奖:把所有参与人的 ID 扔进 Set,随机弹出一个中奖者(保证不会有人重复中奖)。
5. ZSet(有序集合)—— 一个“带分数的排行榜”
它和 Set 一样不能重复,但每个元素都多了一个**“分数”(Score)**,Redis 会根据分数自动排好序。
- 通俗理解:就像班级成绩单。名字不能重复,但每个人都有分数,老师根据分数高低排座位。
- 怎么用:需要实时排序的场景。
- 生活场景:
-
- 游戏排行榜:玩家 ID 是元素,积分是分数。Redis 会自动算出谁是第一名。
- 热搜榜:关键词是元素,搜索热度是分数。
| 类型 | 特点 | 像什么 | 一句话口诀 |
|---|---|---|---|
| String | 简单、万能 | 标签纸 | 哪里需要存哪里 |
| Hash | 结构化、存对象 | 档案袋 | 存人存物存信息 |
| List | 有序、可重复 | 队列 | 先来后到有序排 |
| Set | 无序、不重复 | 抽奖箱 | 找找咱们共同点 |
| ZSet | 有序、带权重 | 成绩单 | 谁分最高排最前 |
Redis支持五种基本的数据结构,分别是String(字符串),Hash(哈希),List(列表),Set(集合),Zset(即Sorted Set有序集合),这些数据结构类型和我们使用的开发语言的数据结构类型其实是相对应的。
注:mybatis框架和mapper都是mysql数据库才有的,记得在yml加上redis配置
# --- 新增 Redis 配置 ---
redis:
host: localhost
port: 6379
password: # 我没有设置密码,所以空着就行
database: 0
lettuce:
pool:
max-active: 8
String类型的增删改查
// 增加和修改
void setString(String key, String value);
// 查询
String getString(String key);
// 删除
Boolean deleteString(String key);
@Override
public void setString(String key, String value) {
// opsForValue 代表操作 String 类型
redisTemplate.opsForValue().set(key, value);
}
@Override
public String getString(String key) {
return redisTemplate.opsForValue().get(key);
}
@Override
public Boolean deleteString(String key) {
// 返回 true 表示删除成功,false 表示 key 本来就不存在
return redisTemplate.delete(key);
}
@GetMapping("/set")
public String set(String key, String value) {
redisService.setString(key, value);
return "成功存入/修改数据!";
}
@GetMapping("/get")
public String get(String key) {
String res = redisService.getString(key);
return "查询结果为:" + (res == null ? "数据为空" : res);
}
@GetMapping("/del")
public String del(String key) {
Boolean success = redisService.deleteString(key);
return success ? "删除成功" : "删除失败,该数据不存在";
}
设置过期时间
Hash类型的增删改查
void hSet(String key, String field, String value);
Object hGet(String key, String field);//查单个
Map<Object, Object> hGetAll(String key);//查全部
Long hDel(String key, String field);
@Override
public void hSet(String key, String field, String value) {
// opsForHash 代表操作 Hash 类型
redisTemplate.opsForHash().put(key, field, value);
}
@Override
public Object hGet(String key, String field) {
return redisTemplate.opsForHash().get(key, field);
}
@Override
public Map<Object, Object> hGetAll(String key) {
return redisTemplate.opsForHash().entries(key);
}
@Override
public Long hDel(String key, String field) {
return redisTemplate.opsForHash().delete(key, field);
}
@GetMapping("/hash/set")
public String hset(String id, String field, String value) {
String key = "user:" + id;
redisService.hSet(key, field, value);
return "【Hash成功】档案袋 " + key + " 中的 " + field + " 已存入:" + value;
}
@GetMapping("/hash/get")
public Object hget(String id, String field) {
return redisService.hGet("user:" + id, field);
}
@GetMapping("/hash/get-all")
public Map<Object, Object> hgetAll(String id) {
return redisService.hGetAll("user:" + id);
}
List类型的增删改查
void lPush(String key, String value);
List<String> lGetAll(String key);
String lPop(String key);//删除
@Override
public void lPush(String key, String value) {
// opsForList 代表操作 List 类型,rightPush 是从右边放进去
redisTemplate.opsForList().rightPush(key, value);
}
@Override
public List<String> lGetAll(String key) {
// range(key, 0, -1) 代表获取从第一个到最后一个的所有数据
return redisTemplate.opsForList().range(key, 0, -1);
}
@Override
public String lPop(String key) {
// leftPop 相当于把队伍最前面的那个人请出来
return redisTemplate.opsForList().leftPop(key);
}
@GetMapping("/list/push")
public String lpush(String id, String content) {
String key = "history:" + id;
redisService.lPush(key, content);
return "【List成功】已存入学习记录:" + content;
}
@GetMapping("/list/get-all")
public List<String> lgetAll(String id) {
return redisService.lGetAll("history:" + id);
}
Set类型的增删改查
void sAdd(String key, String value);
Set<String> sGetMembers(String key);
Long sRemove(String key, String value);
Boolean sIsMember(String key, String value);//判断是否存在:检查某个值是否在集合里
@Override
public void sAdd(String key, String value) {
// opsForSet 代表操作 Set 类型
redisTemplate.opsForSet().add(key, value);
}
@Override
public Set<String> sGetMembers(String key) {
// members 获取集合中所有的元素
return redisTemplate.opsForSet().members(key);
}
@Override
public Long sRemove(String key, String value) {
return redisTemplate.opsForSet().remove(key, value);
}
@Override
public Boolean sIsMember(String key, String value) {
return redisTemplate.opsForSet().isMember(key, value);
}
@GetMapping("/set/add")
public String sadd(String date, String userId) {
String key = "checkin:" + date;
redisService.sAdd(key, userId);
return "【Set成功】用户 " + userId + " 已完成 " + date + " 的打卡!";
}
@GetMapping("/set/get-all")
public Set<String> sget(String date) {
return redisService.sGetMembers("checkin:" + date);
}
@GetMapping("/set/del")
public String sdel(String date, String userId) {
Long count = redisService.sRemove("checkin:" + date, userId);
return count > 0 ? "已取消打卡" : "用户未打卡或数据不存在";
}
模拟打卡
Zset类型增删改查
同理与set