Redis知识总结

1. NoSQL


NoSQL(Not Only SQL),不仅仅是SQL,泛指关系型数据库。NoSQL数据库并不是要取代关系型数据库,而是作为关系型数据库的一种补充。

数据库有标准和方言之分,比如SQL可以操作所有RDBMS,但不同RDBMS语法方面会有所差异(sql方言)。

关系型数据库(RDBMS):全都是以表的形式存储数据,以约束维护数据关系,支持事务。

  • 特点:数据结构化存储,语法非常严谨,不容易出错。

  • 常见的有:MySQL、SQLServer、DB2、Oracle、以及国产数据库(达梦和金仓)等

  • 三高问题:

    • 高并发问题:关系型数据库如果要提供高并发的能力,需要的代价比较大。

      高性能问题:快速从海量数据里找到并操作某些数据,成本高昂。

      高扩展性问题:集群+分布式,数据库增加、减少节点,或者做数据的迁移 都非常麻烦。

非关系型数据库(NoSQL):泛指一切不以表形式存储数据、不使用约束维护关系的数据库。

  • 优点:非常灵活,性能强大,高并发,高扩展性(更容易进行水平扩展)。

  • 缺点:不严谨。

  • 常见的有:

    • Reids,键值对结构的数据库。
    • MongoDB,文档型数据库,每一条数据存储成一个json对象。
    • HBase,列式数据库,可以很方便的存储海量数据。
    • Neo4j,图数据库,更适合于维护拓扑结构的关系,比如 人际关系。

2. Redis介绍


Redis官网:https://redis.io/

Redis中文网:http://redis.cn/

image-20240401074525169

Redis,也是NoSQL数据库家族的一员,由一位意大利小哥Salvatore Sanfilippo 用C语言开发的一款开源的高性能键值对(key-value)数据库。据官方爆料说它并发能力很强可以达到100000+的QPS(每秒内查询次数),使得它非常适合作为分布式缓存和消息中间件来使用。

Redis的特点:

  • 基于内存存储,读写性能高。
  • 适合存储热数据(比如 热点商品,新闻,资讯等)
  • 企业应用广泛。(有各种各样的使用场景)

Redis存储数据的value支持很多种数据类型,比如5种常用的数据类型:

  • 字符串 String
  • 列表 List
  • 集合 Set
  • 有序集合 zset (Sorted Set)
  • 哈希 Hash

扩展:Redis默认端口号是6379,对应手机9键中MERZ四个字母,而Merz是一个意大利的女明星,作者极度厌恶这个女星。而且波浪哥这个人平常喜欢玩梗,一次与朋友交流的时候,造了这个词"MERZ",形容愚蠢(与stupid含义相同),当要给Redis设置默认端口号的时候,波浪哥也没多想,直接就把6379拿过来用了。😭

Redis是单线程+多路IO复用技术:???

多路复用是指使用一个线程来检查多个文件描述符( Socket )的就绪状态,比如调用select和poll函数,传入多个文件描述符,如果有一个文件描述符就绪,则返回,否则阻塞直到超时。得到就绪状态后进行真正的操作可以在同一个线程里执行,也可以启动线程执行(比如使用线程池)。


3. Redis的下载与安装


Redis一开始只支持Linux系统,随着Redis的普及和用户群体的扩大,越来越多的开发者希望能够在其他操作系统上使用Redis,包括:linux、macos、windows平台。

3.1 Windows版

1、Windows版的Redis,由微软团队提供:(Microsoft Archive)

  • 下载地址:https://github.com/microsoftarchive/redis/releases

  • 该项目有Redis2和Redis3版本,目前已经停止维护了。

  • 最后一个稳定版是 3.2.100 (2016年发布)。

image-20240331213500497

tporadowski大神,也提供了一个支持windows平台的Redis :

  • 下载地址:https://github.com/tporadowski/redis/releases
  • 支持版本:Reids5

2、Reids的目录结构:

image-20240331215731670

3、Redis的客户端:(用于连接Redis服务器的工具)

  • 命令行客户端,redis-cli
  • 可视化工具,RESP、ARDM、TinyRDM
    • https://github.com/tiny-craft/
    • https://redis.tinycraft.cc/
  • Java代码,Spring Boot Data Redis

4、Redis的使用:

(1)启动Redis服务:

  • 默认启动:双击 redis-server.exe 即可
  • 加载配置文件启动:redis-server.exe redis.windows.conf (在redis工作目录中执行)

image-20240331222115459

(2)使用客户端连接Redis:(需要提供ip,端口,密码)

  • 本机连接:双击 redis-cli.exe 即可

  • 连接其他电脑上的redis:

# 连接其他电脑上的redis命令
redis-cli.exe -h ip地址 -p 端口号 -a 密码

# 例如 通过ip和端口号连接本地redis
redis-cli.exe -h ip 127.0.0.1 -p 6379

3.2 Linux版

下载地址:https://download.redis.io/releases/


4. Redis的数据类型


Redis中的数据都是以键值对的方式存储的。

  • key:始终是字符串或字节数组(最大512MB)

  • value:有5种常见的数据类型 (每种类型都有不同的使用场景)

    • Stirng:字符串,最最常用。
    • hash:哈希结构,相当于Java里的HashMap。(场景:用于存储一组相关的数据,比如购物车,而且每个哈希表可以存储 2^32-1 个键值对)
    • list:列表结构,有序可重复,相当于Java里的LinkedList。(场景:模拟队列)
    • set:无序不重复的数据集合,相当于Java里的HahsSet。(场景:可以做集合间的运算:交集、并集、差集)
    • zset:也叫sorted set,有序不重复的集合,集合中每个元素关联一个分数(score),根据分数升序排序,没有重复元素。(场景:排行榜)

    扩展:bitmap


5. Redis常用命令


Redis常用命令中文手册:https://www.redis.net.cn/order/

5.1 操作字符串的命令

操作字符串的常用命令:

  • SET key value:存数据,如果key存在会覆盖值。

  • GET value:取数据。

  • DEL key:删除key。

  • SETEX key seconds value:存储数据,并设置有效期(单位是秒)。

    • 应用场景:手机验证码、在有效时间内支付。
  • SETNX key value:存储数据,只要在key不存在的情况下,才可以存数据。

    • 应用场景:分布式锁。

扩展命令:

  • TTL key:查看key的过期时间 (不设置过期时间的话,key默认是-1,表示永久有效)

  • INCR key:让key的值自增 (increment 增加,场景:可以作为分布式id)

示例:

127.0.0.1:6379> set name robin # 存一个字符串数据 key是name value是robin
OK
127.0.0.1:6379> get name  # 获取key为name对应的value值
"robin"
127.0.0.1:6379> del name # 删除key为name的数据
(integer) 1
127.0.0.1:6379> get name  # 获取key为name对应的value值,返回值:nil表示获取不到
(nil)

#---------------------------------------------------------------------

127.0.0.1:6379> setex check_code 10 cat # 存一个字符串数据,有效期是10秒,10s后自动消失
OK
127.0.0.1:6379> ttl check_code # 查看key的过期时间
(integer) 2 # 还剩两秒
127.0.0.1:6379> ttl check_code
(integer) -2 # 已过期
127.0.0.1:6379> get check_code  # 到10s了,数据已经没有了
(nil) 

#---------------------------------------------------------------------

127.0.0.1:6379> setnx lock 1 #setnx只有在key不存在时设置key的值
(integer) 1
127.0.0.1:6379> get lock
"1"
127.0.0.1:6379> setnx lock 2
(integer) 0  # 返回值0:表示这个key已经存在了,所以设置失败

5.2 操作哈希结构的命令

image-20240401070107921

Redis中hash是一个string类型的 field 和 value 的映射表,hash特别适合用于存储对象。

操作hash的常用命令:

  • HSET key field value :存数据,把field-value存到key对应的hash表里。
  • HGET key field :取数据,从key对应的hash表里,找到field对应的数据。
  • HDEL key field : 删除数据。从key对应的hash表里,删除掉field
  • HKEYS key : 获取key对应的hash表里,所有field。
  • HVALS key : 获取key对应的hash表里,所有value。
  • HGETALL key : 获取key对应的hash中,所有filed-value对。

示例:

127.0.0.1:6379> hset user1 name tom # 向key为user1的hash表里,存一个fv对
(integer) 1

127.0.0.1:6379> hset user1 age 20
(integer) 1

127.0.0.1:6379> hget user1 age    # 从key为user1的hash表里,获取age的值
"20"

127.0.0.1:6379> hget user1 name # 从key为user1的hash表里,获取name的值
"tom"

127.0.0.1:6379> hkeys user1  # 获取key为user1的hash表里,所有field
1) "name"
2) "age"

127.0.0.1:6379> hvals user1   # 获取key为user1的hash表里,所有value
1) "tom"
2) "20"

127.0.0.1:6379> hdel user1 age  # 从key为user1对应的hash表里,删除字段age
(integer) 1

127.0.0.1:6379> hgetall user1   # 从key为user1对应的hash表里,获取所有filed-value对
1) "name"
2) "tom"

5.3 操作列表的命令

image-20240401065939312

Redis 列表是简单的字符串列表,按照插入顺序排序。

操作列表的常用命令:(push插入、pop弹出)

  • LPUSH key value1 [value2 …]:将一个或多个值,从队列左边插到右边。
  • LRANGE key start stop:获取列表指定范围内的元素。
    • start和stop是索引值,索引从0开始,0表示第一个,-1表示最后一个。
  • RPOP key:移除并获取列表最后一个元素
  • LLEN key:获取列表的长度。
  • BRPOP key1 [key2 …] timeout:移出并获取列表的最后一个元素; 如果列表没有元素将会阻塞列表,直到等待超时或发现可弹出元素为止。

示例:

127.0.0.1:6379> lpush mylist msg1 msg2 msg3 msg4  #向mylist对应的列表里,从左边依次添加数据
(integer) 4
127.0.0.1:6379> lrange mylist 0 3 #从mylist对应的列表里,查询索引0到索引3的数据(包含头和尾)
1) "msg4"
2) "msg3"
3) "msg2"
4) "msg1"
/*
   msg4->msg3->msg2->msg1
*/

127.0.0.1:6379> llen mylist	#从mylist对应的列表里,查询列表的长度
(integer) 4

127.0.0.1:6379> lrange mylist 0 -1 #从mylist对应的列表里,查询索引0到 倒数第1个值(查询全部)
1) "msg4"
2) "msg3"
3) "msg2"
4) "msg1"

127.0.0.1:6379> lrange mylist 0 -2  #从mylist对应的列表里,查询索引0到 倒数第2个值
1) "msg4"
2) "msg3"
3) "msg2"

127.0.0.1:6379> rpop mylist  #从mylist对应的列表里,弹出最右边的值
"msg1"
127.0.0.1:6379> rpop mylist  #从mylist对应的列表里,弹出最右边的值
"msg2"
127.0.0.1:6379> rpop mylist  #从mylist对应的列表里,弹出最右边的值
"msg3"
127.0.0.1:6379> rpop mylist  #从mylist对应的列表里,弹出最右边的值
"msg4"
127.0.0.1:6379> rpop mylist  #从mylist对应的列表里,弹出最右边的值。已经全部弹出,队列里空了
(nil)
127.0.0.1:6379> brpop mylist 5  #从mylist对应的列表里,弹出最右边的值。如果没有值,就等待5s终
(nil)
(5.06s)

5.4 操作set集合的命令

Redis中set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。

操作set集合的常用命令:

  • SADD key member1 [member2 …] :向集合添加一个或多个成员。
  • SREM key member1 [member2 …] :移除集合中一个或多个成员。
  • SMEMBERS key :返回集合中的所有成员。
  • SCARD key :获取集合的长度。
  • SINTER key1 [key2] :返回给定所有集合的交集。
  • SUNION key1 [key2] :返回所有给定集合的并集。
  • SDIFF key1 [key2] :返回给定所有集合的差集。

示例:

127.0.0.1:6379> sadd set1 a b c # 向set1对应的set集合里添加多个成员
(integer) 3

127.0.0.1:6379> smembers set1 # 查询set1对应的set集合里所有的成员
1) "a"
2) "c"
3) "b"

127.0.0.1:6379> sadd set1 c d jackma # 向set1对应的集合里添加多个成员
(integer) 2   # 成功插入2个

127.0.0.1:6379> srandmember set1 # 从set1对应的set集合里随机获取一个
"a"
127.0.0.1:6379> srandmember set1
"jackma"

127.0.0.1:6379> scard set1 # 查询set1对应的set集合里成员的个数
(integer) 5

127.0.0.1:6379> srem set1 b # 从set1对应的set集合里,移除一个成员b
(integer) 1
127.0.0.1:6379> smembers set1
1) "jackma"
2) "c"
3) "a"
4) "d"

set集合运算:(交集、并集、差集)

127.0.0.1:6379> sadd myset1 tom jerry jack rose # 向第1个set集合插入多个成员
127.0.0.1:6379> sadd myset2 tom robin jerry pony # 向第2个set集合插入多个成员

127.0.0.1:6379> sinter myset1 myset2 # sinter取交集:jerry,tom
127.0.0.1:6379> sunion myset1 myset2 # sunion取并集:pony,jack,robin,rose,jerry,tom
127.0.0.1:6379> sdiff myset1 myset2 # sdiff取差集:myset1-myset2=jack,rose
127.0.0.1:6379> sdiff myset2 myset1 # sdiff取差集:myset2-myset1=robin,pony

image-20240401082057278

5.5 操作zset集合的命令

Redis有序集合zset是string类型元素的集合,且不允许有重复成员。每个元素都会关联一个double类型的分值(score) 。

注意事项:

  • zset默认排序规则是升序
  • 排名rank是从0开始,0表示第1名

操作有序集合zset的常用命令:

  • ZADD key score1 member1 [score2 member2 …] :向有序集合添加一个或多个成员,或者更新已存在成员的分数。
  • ZRANGE key start stop [WITHSCORES] :通过索引区间返回有序集合中指定区间内的成员。(默认从小到大)
  • ZINCRBY key increment member :有序集合中对指定成员的分数加上增量 increment。
  • ZREM key member [member …] :移除有序集合中的一个或多个成员。(remove)

示例:

127.0.0.1:6379> zadd java1 80 tom 90 rose 59 toni #添加多个成员 到java1对应的zet集合里
(integer) 3


127.0.0.1:6379> zrank java1 tom #从java1集合里查询tom的排名(从0开始)
(integer) 1

127.0.0.1:6379> zscore java1 tom #从java1集合里查询tom的分值
"80"


127.0.0.1:6379> zrange java1 0 1  #范围查询(索引或排名)区间内的成员,包含头和尾
1) "toni"
2) "tom"


127.0.0.1:6379> zrange java1 0 1 withscores #范围查询(索引或排名)区间内的成员及分值,包含头和尾
1) "toni"
2) "59"
3) "tom"
4) "80"


127.0.0.1:6379> zrange java1 0 -1 withscores # 查询所有成员及分值,-1表示最后一个成员的索引。
1) "toni"
2) "59"
3) "tom"
4) "80"
5) "rose"
6) "90"

127.0.0.1:6379> zadd java1  99 toni #改toni的分值
(integer) 0

127.0.0.1:6379> zrange java1 0 -1 withscores  
1) "tom"
2) "80"
3) "rose"
4) "90"
5) "toni"  
6) "99"


127.0.0.1:6379> zincrby java1  1  toni # 给toni成绩加一分
"100"


127.0.0.1:6379> zrange java1 0 -1 withscores 
1) "tom"
2) "80"
3) "rose"
4) "90"
5) "toni"
6) "100"

127.0.0.1:6379> zrem java1 tom #从java01里删除一个成员tom
(integer) 1

127.0.0.1:6379> zrange java1 0 -1 withscores
1) "rose"
2) "90"
3) "toni"
4) "100"

5.6 Redis通用命令

  • KEYS pattern:查找所有符合给定模式(pattern)的 key,支持通配符 *。

    • keys * :表示查询当前redis实例里所有的key
    • keys xxx*:表示查询当前redis实例里以xxx开头的key
    • keys xxx?: 查询xxx + 一个任意字符的key (类似mysql模糊查询的_)
  • EXISTS key:判断key是否存在

  • TYPE key:返回key所存储value的类型。

  • TTL key:查看key的剩余过期时间(TTL,time to live),以秒为单位。

    • 返回值-2:不存在。
    • 返回值-1:永不过时。
    • 正整数:剩余时间。
  • DEL key: 删除key

    • 返回值1:表示删除成功。

5.7 其他命令

Redis中默认提供了16个数据库,从0开始,初始默认使用0号库,所有库的密码都是相同的。

  • select <dbid>: 切换数据库。 例如:select 1 切换到1号库。
  • dbsize :查看当前数据库中key的数量。
  • flushall:通杀全部库。(清空所有数据库的所有key)

6. 在Java中操作Redis


6.1 Redis的Java客户端

如果我们想要使用Java程序操作Redis,就需要借助一个Redis的Java客户端作为桥梁,这些客户端提供了一系列的API,使得我们可以在Java代码中以编程的方式与Redis进行交互,本质和redis-cli命令行工具执行命令的效果是一样的。

Redis的Java客户端很多,官方推荐的有三种:

  • Jedis:使用最广泛的Java客户端,它提供了一个简单易用的API,可以让你执行各种Redis命令。
  • Lettuce:高性能的Java客户端,它提供了异步API,适用于响应式编程。
  • Redisson:是在Redis的基础上实现的框架。它不仅提供了基本的Redis操作,还提供了许多高级功能,如 分布式锁 等。

而我们的老东家Spring,通过Spring Data Redis模块对Redis的底层操作进行了高度封装(默认使用Lettuce),使得开发者可以通过简单的配置和注解来访问和操作Redis服务。Spring Data Redis是Spring Data家族的一部分,它提供了一系列的抽象,让开发者能够以声明式的方式操作Redis数据库。而在SpringBoot项目中,还可以使用redis起步依赖: spring-boot-starter-data-redis,再次简化开发。

Spring Data Redis官网:https://spring.io/projects/spring-data-redis

image-20240401102529342

在Spring Data Redis项目中,提供了一些高度封装的类,用于更加简便的操作Redis:

  • RedisTemplate:操作Redis的模板类,它提供了操作Redis的一系列方法。(支持自定义序列化机制)
    • 默认使用Jackson库进行序列化和反序列化操作。
    • 会把我们的key和value,以字节数组的形式存储到redis里,不利于我们查找数据。
  • StringRedisTemplate:是RedisTemplate的子类,默认采用String序列化方式,推荐使用。

Spring Data Redis,对相关API进行了归类封装,将同一类型操作封装为operation接口,具体分类如下:

  • ValueOperations:string数据操作。
  • SetOperations:set类型数据操作。
  • ZSetOperations:zset类型数据操作。
  • HashOperations:hash类型的数据操作。
  • ListOperations:list类型的数据操作。

6.2 Spring Data Redis快速入门

1、导入Redis起步依赖

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

2、配置redis连接信息

spring:
  redis:
    host: localhost
    port: 6379
	#password:
    database: 0 #使用0号数据库

3、使用StringRedisTemplate操作Redis:

package com.sky.test;

import com.alibaba.fastjson.JSON;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.*;

import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Redis测试类
 *
 * @author 白豆五
 * @since 2024/4/1 10:52
 */
@SpringBootTest
public class RedisTest {

    // 操作Redis的模板类
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    /**
     * 测试Redis中字符串类型数据的操作。
     */
    @Test
    public void testValue() {
        // 获取Redis字符串操作对象
        ValueOperations valueOperations = stringRedisTemplate.opsForValue();
        // 设置一个键值对
        valueOperations.set("hello", "spring data redis");

        // 获取并打印设置的值
        Object o = valueOperations.get("hello");
        System.out.println(o);

        // 存储一个JSON字符串
        HashMap<String, Object> map = new HashMap<>();
        map.put("username", "tom");
        map.put("age", 18);
        valueOperations.set("mm", JSON.toJSONString(map));
        Object value = valueOperations.get("mm");
        System.out.println(value);

        // 使用setex命令设置键的过期时间
        valueOperations.set("hi1", "我1分钟过期", Duration.ofMinutes(1));
        valueOperations.set("hi2", "我1分钟过期", 1, TimeUnit.MINUTES);

        // 使用setnx命令演示条件设置,当键不存在时设置键值对
        Boolean flag = valueOperations.setIfAbsent("id", 1);
        System.out.println(flag); // 输出true,因为键"id"首次设置

        flag = valueOperations.setIfAbsent("id", 1);
        System.out.println(flag); // 输出false,因为键"id"已存在
    }


    /**
     * 测试Redis的哈希操作
     */
    @Test
    public void testHash() {
        // 获取HashOperations实例,用于操作Redis的哈希表
        HashOperations hashOperations = stringRedisTemplate.opsForHash();

        // 向"user1"的哈希表中添加"username"和"age"键值对
        hashOperations.put("user1", "username", "tom");
        hashOperations.put("user1", "age", 18);

        // 获取"user1"哈希表中"username"键对应的值
        Object username = hashOperations.get("user1", "username");
        System.out.println(username);

        // 获取"user1"哈希表中的所有键
        Set keySet = hashOperations.keys("user1");
        System.out.println(keySet);

        // 获取"user1"哈希表中的所有值
        List valueList = hashOperations.values("user1");
        System.out.println(valueList);
    }


    /**
     * 测试Redis的List操作。
     */
    @Test
    public void testList() {
        // 获取List操作的接口
        ListOperations listOperations = stringRedisTemplate.opsForList();
        // 向列表"list1"的左侧添加三个元素
        listOperations.leftPushAll("list1", "a", "b", "c");

        // 获取列表"list1"的长度
        Long size = listOperations.size("list1");
        System.out.println(size);// 输出列表长度:3

        // 获取列表"list1"中所有元素
        List list = listOperations.range("list1", 0, -1);
        System.out.println(list);// 输出列表内容:[c, b, a]

        // 从列表"list1"的右侧弹出一个元素
        Object element = listOperations.rightPop("list1");
        System.out.println(element);// 输出弹出的元素:a
    }


    /**
     * 测试Redis的Set操作。
     */
    @Test
    public void testSet() {
        // 获取Set操作对象
        SetOperations setOperations = stringRedisTemplate.opsForSet();
        // 向"set1"集合中添加多个成员
        setOperations.add("set1", "a", "b", "c");

        // 获取"set1"集合中的所有成员
        Set set = setOperations.members("set1");
        System.out.println(set);

        // 获取"set1"集合的成员数量
        Long size = setOperations.size("set1");
        System.out.println(size);// 输出集合大小: 3

        // 从"set1"集合中移除成员"c"
        setOperations.remove("set1", "c");
        // 再次获取"set1"集合的成员数量
        size = setOperations.size("set1");
        System.out.println(size);// 输出集合大小: 2
    }


    /**
     * 测试Redis的ZSet(有序集合)操作。
     *
     */
    @Test
    public void testZset() {
        // 获取ZSet操作的接口
        ZSetOperations zSetOperations = stringRedisTemplate.opsForZSet();
        
        // 向"java"键对应的有序集合中添加成员"tom",并设置分数为88
        zSetOperations.add("java", "tom", 88);
        // 添加成员"jack",分数为69
        zSetOperations.add("java", "jack", 69);
        // 添加成员"rose",分数为100
        zSetOperations.add("java", "rose", 100);

        // 获取成员"tom"的分数
        Double tomScore = zSetOperations.score("java", "tom");
        System.out.println(tomScore);// 输出: 88

        // 为成员"tom"的分数增加10
        zSetOperations.incrementScore("java", "tom", 10);
        tomScore = zSetOperations.score("java", "tom");
        System.out.println(tomScore);// 输出: 98

        System.out.println("---------");

        // 获取有序集合"java"中所有成员及其分数
        Set set = zSetOperations.range("java", 0, -1);
        for (Object member : set) {
            // 输出每个成员及其分数
            System.out.println(member + ":" + zSetOperations.score("java", member));
        }
    }



    // 通用命令的操作
    @Test
    public void testCommons() {
        // 判断元素是否存在
        Boolean result = stringRedisTemplate.hasKey("user1");
        System.out.println(result);

        // 判断元素的类型
        DataType type = stringRedisTemplate.type("166java");
        System.out.println(type);

        // 删除元素
        Boolean flag = stringRedisTemplate.delete("166java");
        System.out.println(flag);

        // keys 通配符
        Set set = stringRedisTemplate.keys("li*");
        System.out.println(set);
    }
}
  • 19
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白豆五

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值