Java 接入Redis: 字符串与哈希类型操作命令

Redis命令: string与hash类型的读写、过期与条件设置

纲要

本文进入 Redis 命令实操。Redis 命令按数据类型分类组织,本文覆盖使用频率最高的两类:stringhash

  • 命令体系总览
    • 按数据类型分类:string / hash / list / set / sorted set
    • 另有通用命令:对所有类型生效
  • string 命令
    • SET / GET:基本读写,同 key 后写覆盖前写
    • SETEX:带过期时间写入,验证码场景
    • SETNXkey 不存在才写入,分布式锁底层
  • hash 命令
    • HSET / HGET:按 field 读写
    • HDEL / HKEYS / HVALS / HGETALL
  • 关键返回值
    • nil 等价于 null
    • SETNX 返回 1 成功、0 未执行

命令体系总览

Redis 通过命令操作数据,这一点类似于用 SQL 操作 MySQL

数据库 操作方式 插入 查询
MySQL SQL 语句 insert into 表 ... select ... from 表
Redis Redis 命令 SET key value GET key

由于 Redis 有五种数据类型,命令也按类型分组
#mermaid-svg-lj7YbEBdeq48DshK{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-lj7YbEBdeq48DshK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-lj7YbEBdeq48DshK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-lj7YbEBdeq48DshK .error-icon{fill:#552222;}#mermaid-svg-lj7YbEBdeq48DshK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-lj7YbEBdeq48DshK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-lj7YbEBdeq48DshK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-lj7YbEBdeq48DshK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-lj7YbEBdeq48DshK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-lj7YbEBdeq48DshK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-lj7YbEBdeq48DshK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-lj7YbEBdeq48DshK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-lj7YbEBdeq48DshK .marker.cross{stroke:#333333;}#mermaid-svg-lj7YbEBdeq48DshK svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-lj7YbEBdeq48DshK p{margin:0;}#mermaid-svg-lj7YbEBdeq48DshK .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-lj7YbEBdeq48DshK .cluster-label text{fill:#333;}#mermaid-svg-lj7YbEBdeq48DshK .cluster-label span{color:#333;}#mermaid-svg-lj7YbEBdeq48DshK .cluster-label span p{background-color:transparent;}#mermaid-svg-lj7YbEBdeq48DshK .label text,#mermaid-svg-lj7YbEBdeq48DshK span{fill:#333;color:#333;}#mermaid-svg-lj7YbEBdeq48DshK .node rect,#mermaid-svg-lj7YbEBdeq48DshK .node circle,#mermaid-svg-lj7YbEBdeq48DshK .node ellipse,#mermaid-svg-lj7YbEBdeq48DshK .node polygon,#mermaid-svg-lj7YbEBdeq48DshK .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-lj7YbEBdeq48DshK .rough-node .label text,#mermaid-svg-lj7YbEBdeq48DshK .node .label text,#mermaid-svg-lj7YbEBdeq48DshK .image-shape .label,#mermaid-svg-lj7YbEBdeq48DshK .icon-shape .label{text-anchor:middle;}#mermaid-svg-lj7YbEBdeq48DshK .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-lj7YbEBdeq48DshK .rough-node .label,#mermaid-svg-lj7YbEBdeq48DshK .node .label,#mermaid-svg-lj7YbEBdeq48DshK .image-shape .label,#mermaid-svg-lj7YbEBdeq48DshK .icon-shape .label{text-align:center;}#mermaid-svg-lj7YbEBdeq48DshK .node.clickable{cursor:pointer;}#mermaid-svg-lj7YbEBdeq48DshK .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-lj7YbEBdeq48DshK .arrowheadPath{fill:#333333;}#mermaid-svg-lj7YbEBdeq48DshK .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-lj7YbEBdeq48DshK .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-lj7YbEBdeq48DshK .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lj7YbEBdeq48DshK .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-lj7YbEBdeq48DshK .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lj7YbEBdeq48DshK .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-lj7YbEBdeq48DshK .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-lj7YbEBdeq48DshK .cluster text{fill:#333;}#mermaid-svg-lj7YbEBdeq48DshK .cluster span{color:#333;}#mermaid-svg-lj7YbEBdeq48DshK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-lj7YbEBdeq48DshK .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-lj7YbEBdeq48DshK rect.text{fill:none;stroke-width:0;}#mermaid-svg-lj7YbEBdeq48DshK .icon-shape,#mermaid-svg-lj7YbEBdeq48DshK .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lj7YbEBdeq48DshK .icon-shape p,#mermaid-svg-lj7YbEBdeq48DshK .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-lj7YbEBdeq48DshK .icon-shape .label rect,#mermaid-svg-lj7YbEBdeq48DshK .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lj7YbEBdeq48DshK .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-lj7YbEBdeq48DshK .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-lj7YbEBdeq48DshK :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Redis 常用命令
string 命令

SET / GET / SETEX / SETNX
hash 命令

HSET / HGET / HDEL / HKEYS / HVALS / HGETALL
list 命令

LPUSH / LRANGE / RPOP / LLEN / BRPOP
set 命令

SADD / SMEMBERS / SCARD / SINTER / SUNION / SDIFF / SREM
sorted set 命令

ZADD / ZRANGE / ZINCRBY / ZREM
通用命令

KEYS / EXISTS / TYPE / TTL / DEL

练习环境建议 :命令在 Windows 与 Linux 版的 Redis 上完全一致。练习阶段推荐用 Windows 版------双击 redis-server.exe 启动服务,再双击 redis-cli.exe 打开客户端即可,无需开虚拟机。

string 类型命令

string 是最常用的类型,核心命令有四个。

命令 语法 作用
SET SET key value 设置指定 key 的值
GET GET key 获取指定 key 的值
SETEX SETEX key seconds value 设置值并指定过期时间(秒)
SETNX SETNX key value 仅当 key 不存在时才设置值

SET 与 GET

bash 复制代码
127.0.0.1:6379> SET name 小明
OK
127.0.0.1:6379> GET name
"小明"

返回 OK 表示执行成功。注意 GET 的返回值被双引号 包裹,说明它是 string 类型。

key 不存在时

bash 复制代码
127.0.0.1:6379> GET age
(nil)

nil 等价于 Java 中的 null,表示值不存在。这是 Redis 中表示「空」的统一方式。

数值也会被存成字符串

bash 复制代码
127.0.0.1:6379> SET age 20
OK
127.0.0.1:6379> GET age
"20"

注意:即使写入时 20 没有加引号,取回时仍带双引号。只要使用 SET 命令,存入的数据最终都会转为字符串存储

相同 key 会覆盖

bash 复制代码
127.0.0.1:6379> SET age 30
OK
127.0.0.1:6379> GET age
"30"

后设置的 30 覆盖了先前的 20。结论:key 相同时,后写入的值覆盖先写入的值

SETEX 设置过期时间

SETEX = SET + EXpire,在写值的同时指定存活秒数。

bash 复制代码
127.0.0.1:6379> SETEX city 10 北京
OK
127.0.0.1:6379> GET city
"北京"

# 等待 10 秒后
127.0.0.1:6379> GET city
(nil)

时间一到,Redis 自动清理该键值对,无需人工干预。
Redis 客户端 Redis 客户端 #mermaid-svg-xTN04bMzlvcPpIrU{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xTN04bMzlvcPpIrU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xTN04bMzlvcPpIrU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xTN04bMzlvcPpIrU .error-icon{fill:#552222;}#mermaid-svg-xTN04bMzlvcPpIrU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xTN04bMzlvcPpIrU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xTN04bMzlvcPpIrU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xTN04bMzlvcPpIrU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xTN04bMzlvcPpIrU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xTN04bMzlvcPpIrU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xTN04bMzlvcPpIrU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xTN04bMzlvcPpIrU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xTN04bMzlvcPpIrU .marker.cross{stroke:#333333;}#mermaid-svg-xTN04bMzlvcPpIrU svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xTN04bMzlvcPpIrU p{margin:0;}#mermaid-svg-xTN04bMzlvcPpIrU .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-xTN04bMzlvcPpIrU text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-xTN04bMzlvcPpIrU .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-xTN04bMzlvcPpIrU .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-xTN04bMzlvcPpIrU .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-xTN04bMzlvcPpIrU .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-xTN04bMzlvcPpIrU #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-xTN04bMzlvcPpIrU .sequenceNumber{fill:white;}#mermaid-svg-xTN04bMzlvcPpIrU #sequencenumber{fill:#333;}#mermaid-svg-xTN04bMzlvcPpIrU #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-xTN04bMzlvcPpIrU .messageText{fill:#333;stroke:none;}#mermaid-svg-xTN04bMzlvcPpIrU .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-xTN04bMzlvcPpIrU .labelText,#mermaid-svg-xTN04bMzlvcPpIrU .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-xTN04bMzlvcPpIrU .loopText,#mermaid-svg-xTN04bMzlvcPpIrU .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-xTN04bMzlvcPpIrU .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-xTN04bMzlvcPpIrU .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-xTN04bMzlvcPpIrU .noteText,#mermaid-svg-xTN04bMzlvcPpIrU .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-xTN04bMzlvcPpIrU .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-xTN04bMzlvcPpIrU .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-xTN04bMzlvcPpIrU .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-xTN04bMzlvcPpIrU .actorPopupMenu{position:absolute;}#mermaid-svg-xTN04bMzlvcPpIrU .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-xTN04bMzlvcPpIrU .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-xTN04bMzlvcPpIrU .actor-man circle,#mermaid-svg-xTN04bMzlvcPpIrU line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-xTN04bMzlvcPpIrU :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 倒计时至第 10 秒 SETEX city 10 北京 OK GET city(第 1 秒) "北京" 自动清理 city GET city(第 11 秒) (nil)

典型应用------手机验证码登录 :服务端生成验证码后存入 Redis 并设置 5 分钟有效期,时间到自动失效。这样无需在应用层维护过期逻辑,也避免了 Session 的局限性。

bash 复制代码
# 验证码 5 分钟有效
SETEX code:13800138000 300 1234

SETNX 条件设置

SETNX = SET if Not eXists只有当 key 不存在时才设置,已存在则不做任何操作。

bash 复制代码
127.0.0.1:6379> SETNX k1 value1
(integer) 1
127.0.0.1:6379> SETNX k1 value2
(integer) 0
127.0.0.1:6379> GET k1
"value1"
返回值 含义
1 设置成功(key 原先不存在)
0 未执行(key 已存在)

第二次 SETNX k1 value2 返回 0,且 GET k1 仍为 value1,说明第二次写入被跳过。

典型应用------分布式锁 :分布式环境下的并发控制依赖「抢锁」这一原子动作,而 SETNX 的「不存在才设置」语义正是抢锁的底层实现原理。
#mermaid-svg-kW2eaQFfeFm1QPwN{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kW2eaQFfeFm1QPwN .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kW2eaQFfeFm1QPwN .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kW2eaQFfeFm1QPwN .error-icon{fill:#552222;}#mermaid-svg-kW2eaQFfeFm1QPwN .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kW2eaQFfeFm1QPwN .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kW2eaQFfeFm1QPwN .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kW2eaQFfeFm1QPwN .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kW2eaQFfeFm1QPwN .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kW2eaQFfeFm1QPwN .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kW2eaQFfeFm1QPwN .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kW2eaQFfeFm1QPwN .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kW2eaQFfeFm1QPwN .marker.cross{stroke:#333333;}#mermaid-svg-kW2eaQFfeFm1QPwN svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kW2eaQFfeFm1QPwN p{margin:0;}#mermaid-svg-kW2eaQFfeFm1QPwN .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-kW2eaQFfeFm1QPwN .cluster-label text{fill:#333;}#mermaid-svg-kW2eaQFfeFm1QPwN .cluster-label span{color:#333;}#mermaid-svg-kW2eaQFfeFm1QPwN .cluster-label span p{background-color:transparent;}#mermaid-svg-kW2eaQFfeFm1QPwN .label text,#mermaid-svg-kW2eaQFfeFm1QPwN span{fill:#333;color:#333;}#mermaid-svg-kW2eaQFfeFm1QPwN .node rect,#mermaid-svg-kW2eaQFfeFm1QPwN .node circle,#mermaid-svg-kW2eaQFfeFm1QPwN .node ellipse,#mermaid-svg-kW2eaQFfeFm1QPwN .node polygon,#mermaid-svg-kW2eaQFfeFm1QPwN .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-kW2eaQFfeFm1QPwN .rough-node .label text,#mermaid-svg-kW2eaQFfeFm1QPwN .node .label text,#mermaid-svg-kW2eaQFfeFm1QPwN .image-shape .label,#mermaid-svg-kW2eaQFfeFm1QPwN .icon-shape .label{text-anchor:middle;}#mermaid-svg-kW2eaQFfeFm1QPwN .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-kW2eaQFfeFm1QPwN .rough-node .label,#mermaid-svg-kW2eaQFfeFm1QPwN .node .label,#mermaid-svg-kW2eaQFfeFm1QPwN .image-shape .label,#mermaid-svg-kW2eaQFfeFm1QPwN .icon-shape .label{text-align:center;}#mermaid-svg-kW2eaQFfeFm1QPwN .node.clickable{cursor:pointer;}#mermaid-svg-kW2eaQFfeFm1QPwN .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-kW2eaQFfeFm1QPwN .arrowheadPath{fill:#333333;}#mermaid-svg-kW2eaQFfeFm1QPwN .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-kW2eaQFfeFm1QPwN .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-kW2eaQFfeFm1QPwN .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kW2eaQFfeFm1QPwN .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-kW2eaQFfeFm1QPwN .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kW2eaQFfeFm1QPwN .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-kW2eaQFfeFm1QPwN .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-kW2eaQFfeFm1QPwN .cluster text{fill:#333;}#mermaid-svg-kW2eaQFfeFm1QPwN .cluster span{color:#333;}#mermaid-svg-kW2eaQFfeFm1QPwN div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-kW2eaQFfeFm1QPwN .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-kW2eaQFfeFm1QPwN rect.text{fill:none;stroke-width:0;}#mermaid-svg-kW2eaQFfeFm1QPwN .icon-shape,#mermaid-svg-kW2eaQFfeFm1QPwN .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kW2eaQFfeFm1QPwN .icon-shape p,#mermaid-svg-kW2eaQFfeFm1QPwN .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-kW2eaQFfeFm1QPwN .icon-shape .label rect,#mermaid-svg-kW2eaQFfeFm1QPwN .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kW2eaQFfeFm1QPwN .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-kW2eaQFfeFm1QPwN .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-kW2eaQFfeFm1QPwN :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 服务实例 A

SETNX lock 1

返回 1 抢锁成功
获得锁

执行业务

DEL lock 释放
服务实例 B

SETNX lock 1

返回 0 抢锁失败
等待或放弃

string 类型的完整命令远不止这四个(官方文档共 20 个)。完整的命令清单可查阅 Redis 中文网 http://www.redis.net.cn 的「Redis 教程」菜单。

hash 类型命令

hash 是一个 string 类型的 fieldvalue 的映射表,特别适合存储对象。

三层结构

#mermaid-svg-fsWODK0uvZxwXH8T{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-fsWODK0uvZxwXH8T .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fsWODK0uvZxwXH8T .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fsWODK0uvZxwXH8T .error-icon{fill:#552222;}#mermaid-svg-fsWODK0uvZxwXH8T .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fsWODK0uvZxwXH8T .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fsWODK0uvZxwXH8T .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fsWODK0uvZxwXH8T .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fsWODK0uvZxwXH8T .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fsWODK0uvZxwXH8T .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fsWODK0uvZxwXH8T .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fsWODK0uvZxwXH8T .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fsWODK0uvZxwXH8T .marker.cross{stroke:#333333;}#mermaid-svg-fsWODK0uvZxwXH8T svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fsWODK0uvZxwXH8T p{margin:0;}#mermaid-svg-fsWODK0uvZxwXH8T .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-fsWODK0uvZxwXH8T .cluster-label text{fill:#333;}#mermaid-svg-fsWODK0uvZxwXH8T .cluster-label span{color:#333;}#mermaid-svg-fsWODK0uvZxwXH8T .cluster-label span p{background-color:transparent;}#mermaid-svg-fsWODK0uvZxwXH8T .label text,#mermaid-svg-fsWODK0uvZxwXH8T span{fill:#333;color:#333;}#mermaid-svg-fsWODK0uvZxwXH8T .node rect,#mermaid-svg-fsWODK0uvZxwXH8T .node circle,#mermaid-svg-fsWODK0uvZxwXH8T .node ellipse,#mermaid-svg-fsWODK0uvZxwXH8T .node polygon,#mermaid-svg-fsWODK0uvZxwXH8T .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fsWODK0uvZxwXH8T .rough-node .label text,#mermaid-svg-fsWODK0uvZxwXH8T .node .label text,#mermaid-svg-fsWODK0uvZxwXH8T .image-shape .label,#mermaid-svg-fsWODK0uvZxwXH8T .icon-shape .label{text-anchor:middle;}#mermaid-svg-fsWODK0uvZxwXH8T .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-fsWODK0uvZxwXH8T .rough-node .label,#mermaid-svg-fsWODK0uvZxwXH8T .node .label,#mermaid-svg-fsWODK0uvZxwXH8T .image-shape .label,#mermaid-svg-fsWODK0uvZxwXH8T .icon-shape .label{text-align:center;}#mermaid-svg-fsWODK0uvZxwXH8T .node.clickable{cursor:pointer;}#mermaid-svg-fsWODK0uvZxwXH8T .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-fsWODK0uvZxwXH8T .arrowheadPath{fill:#333333;}#mermaid-svg-fsWODK0uvZxwXH8T .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-fsWODK0uvZxwXH8T .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-fsWODK0uvZxwXH8T .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fsWODK0uvZxwXH8T .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-fsWODK0uvZxwXH8T .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fsWODK0uvZxwXH8T .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-fsWODK0uvZxwXH8T .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-fsWODK0uvZxwXH8T .cluster text{fill:#333;}#mermaid-svg-fsWODK0uvZxwXH8T .cluster span{color:#333;}#mermaid-svg-fsWODK0uvZxwXH8T div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fsWODK0uvZxwXH8T .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-fsWODK0uvZxwXH8T rect.text{fill:none;stroke-width:0;}#mermaid-svg-fsWODK0uvZxwXH8T .icon-shape,#mermaid-svg-fsWODK0uvZxwXH8T .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fsWODK0uvZxwXH8T .icon-shape p,#mermaid-svg-fsWODK0uvZxwXH8T .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-fsWODK0uvZxwXH8T .icon-shape .label rect,#mermaid-svg-fsWODK0uvZxwXH8T .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fsWODK0uvZxwXH8T .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-fsWODK0uvZxwXH8T .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-fsWODK0uvZxwXH8T :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} key

如 001
value 整体为 hash
field: name

value: 小明
field: age

value: 20
field: phone

value: 138***

命令参数与结构的对应关系:

命令参数 对应结构
key 整个 Redis 键值对的 key
field value 内部的字段名
value field 对应的值

重点HDEL 删除的是 key 下的某个 field不是删除整个 key 。这是初学 hash 最常见的误解。

命令 语法 作用
HSET HSET key field value 设置 keyfield 的值
HGET HGET key field 获取 keyfield 的值
HDEL HDEL key field [field ...] 删除一个或多个 field
HKEYS HKEYS key 返回所有 field
HVALS HVALS key 返回所有 value
HGETALL HGETALL key 返回所有 fieldvalue

HSET 与 HGET

以存储用户信息为例,用用户 ID 作为 key ,属性作为 field

bash 复制代码
127.0.0.1:6379> HSET 001 name 小明
(integer) 1
127.0.0.1:6379> HSET 001 age 20
(integer) 1

127.0.0.1:6379> HGET 001 name
"小明"
127.0.0.1:6379> HGET 001 age
"20"

两个 HSET 使用同一个 key001,因此代表同一个用户对象的不同属性。

HDEL 删除字段

bash 复制代码
127.0.0.1:6379> HDEL 001 age
(integer) 1

127.0.0.1:6379> HGET 001 age
(nil)

HDEL 后可接多个 field,一次性删除多个字段。删除后该 field 变为 nil

HKEYS / HVALS / HGETALL

bash 复制代码
127.0.0.1:6379> HKEYS 001
1) "name"
2) "age"

127.0.0.1:6379> HVALS 001
1) "小明"
2) "20"

127.0.0.1:6379> HGETALL 001
1) "name"
2) "小明"
3) "age"
4) "20"

三者的区别:

命令 返回内容
HKEYS 仅所有 field
HVALS 仅所有 value
HGETALL fieldvalue 交替列出

HGETALL 的输出是 fieldvaluefieldvalue 交替排列,需成对阅读。

key 本身不存在(如 HGET 002 name),同样返回 nil

完整可运行代码

Java 中对应的操作

java 复制代码
package com.itheima.test;

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.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 演示 Redis string 与 hash 类型命令在 Java 中的对应操作。
 */
@SpringBootTest
public class RedisStringHashCommandTest {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 对应 SET / GET:基本读写。
     */
    @Test
    public void testSetAndGet() {
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();

        ops.set("name", "小明");
        System.out.println("GET name -> " + ops.get("name"));

        // key 不存在时返回 null,等价于命令行中的 nil
        System.out.println("GET notExist -> " + ops.get("notExist"));

        // 相同 key 后写覆盖前写
        ops.set("age", "20");
        ops.set("age", "30");
        System.out.println("GET age -> " + ops.get("age"));
    }

    /**
     * 对应 SETEX:写入时指定过期时间。
     */
    @Test
    public void testSetex() {
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();

        // 验证码 5 分钟有效
        ops.set("code:13800138000", "1234", 5, TimeUnit.MINUTES);

        System.out.println("GET code -> " + ops.get("code:13800138000"));
        System.out.println("剩余有效期(秒)-> " + redisTemplate.getExpire("code:13800138000"));
    }

    /**
     * 对应 SETNX:key 不存在才设置,可用于分布式锁。
     */
    @Test
    public void testSetnx() {
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();

        redisTemplate.delete("k1");

        Boolean first = ops.setIfAbsent("k1", "value1");
        Boolean second = ops.setIfAbsent("k1", "value2");

        System.out.println("第一次 SETNX -> " + first);
        System.out.println("第二次 SETNX -> " + second);
        System.out.println("GET k1 -> " + ops.get("k1"));
    }

    /**
     * 对应 HSET / HGET / HDEL / HKEYS / HVALS / HGETALL。
     */
    @Test
    public void testHash() {
        HashOperations<String, Object, Object> ops = redisTemplate.opsForHash();

        ops.put("001", "name", "小明");
        ops.put("001", "age", "20");

        System.out.println("HGET 001 name -> " + ops.get("001", "name"));

        System.out.println("HKEYS 001 -> " + ops.keys("001"));
        System.out.println("HVALS 001 -> " + ops.values("001"));
        System.out.println("HGETALL 001 -> " + ops.entries("001"));

        // HDEL 删除的是 field,而非整个 key
        ops.delete("001", "age");
        Map<Object, Object> after = ops.entries("001");
        System.out.println("删除 age 后 HGETALL -> " + after);

        // 验证 key 本身仍然存在
        System.out.println("key 001 是否存在 -> " + Boolean.TRUE.equals(redisTemplate.hasKey("001")));
    }
}

工程目录结构

txt 复制代码
springdataredis_demo/
├── pom.xml
└── src/
    ├── main/
    │   ├── java/com/itheima/
    │   │   ├── App.java
    │   │   └── config/
    │   │       └── RedisConfig.java
    │   └── resources/
    │       └── application.yml
    └── test/
        └── java/com/itheima/test/
            └── RedisStringHashCommandTest.java

API 速览

Redis 命令 RedisTemplate 对应方法 说明
SET key value opsForValue().set(k, v) 设置值
GET key opsForValue().get(k) 取值,不存在返回 null
SETEX key sec value opsForValue().set(k, v, timeout, unit) 带过期时间写入
SETNX key value opsForValue().setIfAbsent(k, v) 不存在才设置,返回 Boolean
HSET key f v opsForHash().put(k, f, v) 设置字段
HGET key f opsForHash().get(k, f) 取字段值
HDEL key f opsForHash().delete(k, f) 删除字段
HKEYS key opsForHash().keys(k) 所有 field
HVALS key opsForHash().values(k) 所有 value
HGETALL key opsForHash().entries(k) 所有 field-value
TTL key getExpire(k) 剩余有效期
EXISTS key hasKey(k) 键是否存在

官方文档

总结

本文覆盖了 stringhash 两类高频命令。string 的四个命令体现了三种写入语义:普通写入(SET,同键覆盖)、带过期写入(SETEX,验证码场景)、条件写入(SETNX,返回 1/0,分布式锁底层)。hash 的核心是理解 key → field → value 三层结构------命令中的 field 位于 value 内部,因此 HDEL 删的是字段而非整个键。Redis 统一用 nil 表达「不存在」,对应 Java 中的 null

相关推荐
智慧物业老杨5 小时前
物业数字化落地思考:真正的转型,是底层数据秩序的重构
java·大数据·人工智能·微服务·系统架构
星空8 小时前
金蝶苍穹build.gradle配置
java·build.gradle
充电zcx8 小时前
Linux:4:开发工具详解
linux·运维·服务器
步行cgn11 小时前
Spring 基于 XML 的自动装配:byName 详解
java·后端·spring
大帅点兵11 小时前
Apache Ant 1.9.9 完整讲解
java
LuTshoes11 小时前
spring ai 实战 手搓 PlaneExecuteAgent
java·人工智能·spring·ai
这料鬼有毒12 小时前
二刷hot100-73.矩阵置零
java
caoerzhong12 小时前
JeeWMS 开源仓库管理系统二次开发与接口对接实战:Java WMS 如何与 ERP、MES 和自动化设备打通
java·开源
长谷深风11112 小时前
评测AI Agent:三种裁判各司其职
java·大数据·开发语言·人工智能·ai agent