news 2026/5/11 6:57:18

【Redis】Redis基础——Redis命令

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Redis】Redis基础——Redis命令

一、Redis 的数据结构

Redis是一个key-value的数据库,的key一般是String类型,不过value类型多种多样:

二、通用命令

使用命令登录: redis-cli -h IP -p redis端口 -a “redis登录密码”

Redis为了方便我们学习,操作不同数据类型的命令也做了分组,在官网https://redis.io/commands可以查看到不同的命令:

  • 查看通用的命令:

help @generic

查看单个命令的帮助,如 help keys

查看符合模板的key,不建议在生产设备使用。因为redis是单线程的,在搜索符合的模板是会阻塞其他的命令,在集群中应避免在主节点使用该命令。

  • 批量插入key,value值

MSET key1 value1 …… key n value n

  • 删除一个指定的key

DEL key

  • 判断key是否存在,存在返回1,不存在返回0

EXISTS key

  • 给一个key设置有效期(单位是秒),有效期到期时该key会被自动删除

EXPIRE key 时间数

  • 查看一个KEY的剩余有效期

TTL key

如果值为 -1 代表永久有效

三 、String 类型

String类型,也就是字符串类型,是Redis中最简单的存储类型。其value是字符串,不过根据字符串的格式不同,又可以分为3类:

  1. string:普通字符串
  2. int:整数类型,可以做自增、自减操作
  3. float:浮点类型,可以做自增、自减操作

String 类型常用命令

  • SET:添加或者修改已经存在的一个String类型的键值对

  • GET:根据key获取String类型的value

  • MSET:批量添加多个String类型的键值对

  • MGET:根据多个key获取多个String类型的value

  • INCR:让一个整型的key自增1

  • INCRBY:让一个整型的key自增并指定步长,例如:incrby num 2 让num值自增2

  • INCRBYFLOAT:让一个浮点类型的数字自增并指定步长

  • SETNX:添加一个String类型的键值对,前提是这个key不存在,否则不执行

  • SETEX:添加一个String类型的键值对,并且指定有效期

插入key 为 teacher, value 为 zhangsan的键值对,10秒过后再次取值已经失效了。

扩展

Redis没有类似MySQL中的Table的概念,我们该如何区分不同类型的key呢?例如,需要存储用户、商品信息到redis,有一个用户id是1,有一个商品id恰好也是1

redis 的 key 允许多个单词用 : 隔开,格式可以是项目名:业务名:类型:id。这个格式并非固定,可以按照实际需求。

四、Hash 类型

Hash类型,也叫散列,其value是一个无序字典,类似于Java中的HashMap结构。

String 结构是将对象序列化为JSON后存储,需要修改某个字段时不方便。

Hash 结构可以将对象中的每个字段单独存储,可以对单个字段进行CRUD

常见命令

  • HSET key field value:添加或者修改hash类型keyfield的值

添加

修改年龄

  • HGET key field:获取一个hash类型keyfield的值

  • HMSET:批量添加多个hash类型keyfield的值

添加一个key为 it:user:4 的 hash数据,插入了name = LiLei,age = 20 , sex = man 三个字段。

  • HMGET:获取指定key的多个字段值

获取key为 it:user:4 的 name、age 、sex字段。

  • HGETALL:获取指定key的所有字段和值

  • HKEYS:获取指定key的所有字段

  • HVALS:获取指定key的所有值

  • HINCRBY: 指定key的某个字段值自增并指定步长

  • HSETNX:根据指定key值添加新字段,前提是这个field不存在,否则不执行

五、List类型

Redis中的List类型与Java中的LinkedList类似,可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。

特征和LinkeList相似:有序、可重复、插入和删除快、查询效率一般

常用来存储一个有序数据,例如:朋友圈点赞列表,评论列表等。

List常见命令

  • LPUSH key element ... :向列表左侧插入一个或多个元素,返回列表总个数

  • LPOP key:移除并返回列表左侧的第一个元素,没有则返回nil

  • RPUSH key element ... :向列表右侧插入一个或多个元素,返回列表总个数

  • RPOP key [count]:移除并返回列表右侧的第一个元素

可以跟取出的个数,如 rpop user 5,表示在key为user的列表中取出5个元素

  • LRANGE key star end:返回一段下标范围内的所有元素

如取出下标为 0 到 2 范围内列表的元素

  • BLPOP和BRPOP:与LPOP和RPOP类似,只不过在没有元素时等待指定时间(单位 秒),而不是直接返回nil。

L 表示左边,R表示右边。

思考

如何利用List结构模拟一个栈?

  • 入口和出口在同一边

如何利用List结构模拟一个队列?

  • 入口和出口在不同边

如何利用List结构模拟一个阻塞队列?

  • 入口和出口在不同边
  • 出队时采用BLPOP或BRPOP

六、Set类型

  • Redis的Set结构与Java中的HashSet类似,可以看做是一个value为null的HashMap。因为也是一个hash表,因此具备与HashSet类似的特征:无序、不可重复、查找快、支持交集、并集
  • SADD key member ... :向set中添加一个或多个元素

在队列s2中添加值 1,3,4,6

  • SREM key member ... : 移除set中的指定元素

移除队列名为s1的,且值为4的元素

  • SCARD key: 返回set中元素的个数

  • SISMEMBER key member:判断一个元素是否存在于set中

存在返回1, 不存在返回0

  • SMEMBERS:获取set中的所有元素

  • SINTER key1 key2 ... :求key1与key2的交集

显示s1 和 s2 的所有元素,并取 s1 和 s2 的交集

  • SDIFF key1 key2 ... :求key1与key2的差集

  • SUNION key1 key2 ..:求key1和key2的并集

七、SortedSet类型

Redis的SortedSet是一个可排序的set集合,与Java中的TreeSet有些类似,但底层数据结构却差别很大。SortedSet中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现是一个跳表(SkipList)加 hash表。

  • ZADD key score member:添加一个或多个元素到sorted set,如果已经存在则更新其score

  • ZREM key member:删除sorted set中的一个指定元素

  • ZSCOREkey member :获取sorted set中的指定元素的score
  • ZRANK key member:获取sorted set中的指定元素的排名

  • ZCARDkey:获取sorted set中的元素个数
  • ZCOUNT key min max:统计score值在给定范围内的所有元素的个数

  • ZINCRBY key increment member:让sorted set中的指定元素自增,步长为指定的increment
  • ZRANGE key min max:按照score排序后,获取指定排名范围内的元素

升序获取前三名的元素

降序后获取前三名

  • ZRANGEBYSCORE key min max:按照score排序后,获取指定score范围内的元素
  • ZDIFFZINTERZUNION:求差集、交集、并集

注意:所有的排名默认都是升序,如果要降序则在命令的Z后面添加REV即可

八、Redis的JAVA客户端

1. Jedis

1.1 Jedis 使用步骤

  • 引入 Jedis 依赖
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.7.0</version> </dependency>
  • 注入模板,建立连接

/* 初始化 jedis */ @BeforeEach void setUp() { // 建立连接 jedis = new Jedis("192.168.30.130"); // 设置密码 jedis.auth("123456"); // 选择库 jedis.select(0); }
  • 使用 Jedis 操作数据
@Test void testString() { // 插入数据 String result = jedis.set("name", "张三"); System.out.println("result = " + result ); // 获取数据 String name = jedis.get("name"); System.out.println("name = " + name); }
  • 释放连接
/* 释放资源 */ @AfterEach void tearDown() { if (jedis != null) { jedis.close(); } }

整体代码如下:

@SpringBootTest class JedisDemoApplicationTests { private Jedis jedis; /* 初始化 jedis */ @BeforeEach void setUp() { // 建立连接 jedis = new Jedis("192.168.30.130"); // 设置密码 jedis.auth("123456"); // 选择库 jedis.select(0); } @Test void testString() { // 插入数据 String result = jedis.set("name", "张三"); System.out.println("result = " + result ); // 获取数据 String name = jedis.get("name"); System.out.println("name = " + name); } /* 释放资源 */ @AfterEach void tearDown() { if (jedis != null) { jedis.close(); } } }

1.2 Jedis 连接池

Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此我们推荐大家使用Jedis连接池代替Jedis的直连方式。

1. 创建一个名为JedisConnectPool的连接池工具类。

package com.example.jedis_demo.util; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; /** * Jedis 连接池 * */ public class JedisConnectPool { // 定义一个常量 private static final JedisPool JEDIS_POOL; static { // 配置连接池 JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); // 最大连接数量 jedisPoolConfig.setMaxTotal(8); // 最大空闲连接数量 jedisPoolConfig.setMaxIdle(8); // 最小空闲连接数量 jedisPoolConfig.setMinIdle(0); // 创建连接, 1000ms 表示等待时间 JEDIS_POOL = new JedisPool(jedisPoolConfig, "192.168.30.130", 6379, 1000, "123456"); } // 获取 Jedis 对象 public static Jedis getJedis() { return JEDIS_POOL.getResource(); } }

2. 使用连接池

@SpringBootTest class JedisDemoApplicationTests { private Jedis jedis; /* 初始化 jedis */ @BeforeEach void setUp() { /* // 建立连接 jedis = new Jedis("192.168.30.130"); // 设置密码 jedis.auth("123456");*/ jedis = JedisConnectPool.getJedis(); // 选择库 jedis.select(0); } @Test void testString() { // 插入数据 String result = jedis.set("name", "张三"); System.out.println("result = " + result ); // 获取数据 String name = jedis.get("name"); System.out.println("name = " + name); } /* 释放资源 */ @AfterEach void tearDown() { if (jedis != null) { jedis.close(); } } }

2. SpringDataRedis

现在多数的项目都是基于SpringBoot的,如何在SpringBoot中整合 Jedis 呢?

SpringData 是 Spring 中数据操作的模块,包含了各种数据库的集成,其中对redis数据库的继承模块叫做SpringDataRedis。官网地址:Spring Data Redis

  • 提供了对不同Redis客户端的整合(Lettuce和Jedis)
  • 提供了RedisTemplate统一API来操作Redis
  • 支持Redis的发布订阅模型
  • 支持Redis哨兵和Redis集群
  • 支持基于Lettuce的响应式编程
  • 支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化
  • 支持基于Redis的JDKCollection实现

SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:

2.1 使用步骤

  • 引入spring-boot-starter-data-redis 依赖
  • 编写yml配置文件, 配置 Redis
  • 注入 redisTemplate并使用

1. 引入依赖

<!-- 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>

2.编写yml配置文件, 配置 Redis

spring: redis: port: 6379 # redis 端口 host: 192.168.30.130 # 服务器IP password: 123456 # 密码 jedis: pool: max-active: 8 # 最大连接数量 max-idle: 8 # 最大空闲连接数 min-idle: 0 #最小空闲连接数 max-wait: 100 #等待连接时间

3.注入 redisTemplate并使用

@SpringBootTest class RedisTemplateDempApplicationTests { @Autowired private RedisTemplate redisTemplate; @Test void testString() { // 插入数据 redisTemplate.opsForValue().set("name", "赵六"); // 读取数据 Object name = redisTemplate.opsForValue().get("name"); System.out.println("name = " + name); } }

2.2 SpringDataRedis的序列化方式

RedisTemplate可以接收任意Object作为值写入Redis,只不过写入前会把Object序列化为字节形式,默认是采用JDK序列化,得到的结果如下图所示,缺点是可读性差、占用内存大

可以使用自定义RedisTemplate 序列化方式。

1. 添加jackson依赖

<!-- jackson 序列化--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency>

2. 新建Redis配置类,设置key、value 的序列化方式。

@Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { // 1. 创建 redisTemplate 对象 RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); // 2. 设置连接工厂 redisTemplate.setConnectionFactory(redisConnectionFactory); // 3. 设置序列化工具 GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer(); // 4. 设置key、hashKey 为String 序列化 redisTemplate.setKeySerializer(RedisSerializer.string()); redisTemplate.setHashKeySerializer(RedisSerializer.string()); // 5. 设置 value、hashValue 为 Json 序列化 redisTemplate.setValueSerializer(jsonRedisSerializer); redisTemplate.setHashKeySerializer(jsonRedisSerializer); return redisTemplate; } }

3. 测试。插入一条Object类型数据,查看是否序列化成功

创建一个实体对象

public class User { private String user; private Integer age; public User() { } public User(String user, Integer age) { this.user = user; this.age = age; } // 省略 get、set方法 }

引入Template 模板

@SpringBootTest class RedisTemplateDempApplicationTests { @Autowired private RedisTemplate<String, Object> redisTemplate; @Test void testString() { // 插入数据 redisTemplate.opsForValue().set("name", "赵六"); // 读取数据 Object name = redisTemplate.opsForValue().get("name"); System.out.println("name = " + name); } @Test void testSavaUser() { // 写入数据 redisTemplate.opsForValue().set("user:1", new User("张无忌", 20)); // 获取数据 User u = (User) redisTemplate.opsForValue().get("user:1"); System.out.println(u); } }

2.3 手动序列化

尽管JSON的序列化方式可以满足我们的需求。但是Json 序列化器为了知道对象的类型,还会把实体类的类型添加上去,额外增加了内存开销。

为了节省内存空间,不采用Json序列化器处理value,而是通过采用String序列化器,但它只能存储String类型的key、value,如果需要存储Obect类型的value,需要手动序列化和反序列化。

Spring默认提供了一个StringRedisTemplate类,它的key和value的序列化方式默认就是String方式。省去了我们自定义RedisTemplate的过程:

// JSON工具 private static final ObjectMapper mapper = new ObjectMapper(); // 序列化,序列化成json对象 String json = mapper.writeValueAsString(实体对象); // 反序列化, 由json变成 实体对象 User user1 = mapper.readValue(val, User.class);

1. 引入序列化器依赖

<!-- jackson 序列化--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency>

2. 注入 StringRedisTemplate, 定义Json工具类

3. 定义实体对象,这里定义了一个 User 对象。

public class User { private String user; private Integer age; public User() { } public User(String user, Integer age) { this.user = user; this.age = age; } // 省略 get、set方法 }

4. 测试

@SpringBootTest class RedisTemplateDempApplicationTests { @Autowired private StringRedisTemplate StringredisTemplate; // JSON工具 private static final ObjectMapper mapper = new ObjectMapper(); @Test void testStringTemplate() throws JsonProcessingException { User user = new User("张无忌1", 20); // 手动序列化 String json = mapper.writeValueAsString(user); // 写入数据 StringredisTemplate.opsForValue().set("user:2", json); // 获取数据 String val = StringredisTemplate.opsForValue().get("user:2"); // 反序列化 User user1 = mapper.readValue(val, User.class); System.out.println(user1); } }

运行结果

3 序列化两种方式总结

方案一:自定义序列化

1. 自定义RedisTemplate

2. 修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer

方案二:手动序列化

1. 使用StringRedisTemplate

2. 写入Redis时,手动把对象序列化为JSON

3. 读取Redis时,手动把读取到的JSON反序列化为对象

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/30 17:43:42

Formtastic终极扩展指南:如何构建可复用的表单插件与组件库

Formtastic终极扩展指南&#xff1a;如何构建可复用的表单插件与组件库 【免费下载链接】formtastic A Rails form builder plugin with semantically rich and accessible markup. 项目地址: https://gitcode.com/gh_mirrors/fo/formtastic Formtastic是一款强大的Rail…

作者头像 李华
网站建设 2026/4/15 4:15:47

VQA系统进入毫秒级响应时代(2026奇点大会闭门报告首次披露)

第一章&#xff1a;VQA系统进入毫秒级响应时代&#xff08;2026奇点大会闭门报告首次披露&#xff09; 2026奇点智能技术大会(https://ml-summit.org) 在2026奇点大会闭门技术报告中&#xff0c;三所联合实验室&#xff08;MIT CSAIL、DeepMind VQA Group、中科院自动化所视觉…

作者头像 李华
网站建设 2026/5/11 6:54:35

HCNW4502-300E,单通道15kV/µs高速TTL兼容光耦合器

简介今天我要向大家介绍的是 Broadcom 的光耦合器——HCNW4502-300E。它是一款单通道高速数字光耦合器&#xff0c;采用绝缘层将LED与集成光电探测器隔开以提供电气绝缘。该器件通过分离光电二极管偏置和输出晶体管集电极连接&#xff0c;有效降低了基极-集电极电容&#xff0c…

作者头像 李华