云计算百科
云计算领域专业知识百科平台

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

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

纲要

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

  • 命令体系总览
    • 按数据类型分类:string / hash / list / set / sorted set
    • 另有通用命令:对所有类型生效
  • string 命令
    • SET / GET:基本读写,同 key 后写覆盖前写
    • SETEX:带过期时间写入,验证码场景
    • SETNX:key 不存在才写入,分布式锁底层
  • 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

127.0.0.1:6379> SET name 小明
OK
127.0.0.1:6379> GET name
"小明"

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

key 不存在时:

127.0.0.1:6379> GET age
(nil)

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

数值也会被存成字符串

127.0.0.1:6379> SET age 20
OK
127.0.0.1:6379> GET age
"20"

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

相同 key 会覆盖

127.0.0.1:6379> SET age 30
OK
127.0.0.1:6379> GET age
"30"

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

SETEX 设置过期时间

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

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 的局限性。

# 验证码 5 分钟有效
SETEX code:13800138000 300 1234

SETNX 条件设置

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

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;}

服务实例 ASETNX lock 1返回 1 抢锁成功

获得锁执行业务DEL lock 释放

服务实例 BSETNX lock 1返回 0 抢锁失败

等待或放弃

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

hash 类型命令

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

三层结构

#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: namevalue: 小明

field: agevalue: 20

field: phonevalue: 138***

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

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

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

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

HSET 与 HGET

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

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 使用同一个 key(001),因此代表同一个用户对象的不同属性。

HDEL 删除字段

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

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 field 与 value 交替列出

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

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

完整可运行代码

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")));
}
}

工程目录结构

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) 键是否存在

官方文档

  • Redis 命令总览:https://redis.io/commands
  • String 命令参考:https://redis.io/commands/?group=string
  • Hash 命令参考:https://redis.io/commands/?group=hash
  • Redis 中文网教程:http://www.redis.net.cn/tutorial/3501.html

总结

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

赞(0)
未经允许不得转载:网硕互联帮助中心 » Java 接入Redis: 字符串与哈希类型操作命令
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!