


专栏:Redis 修行录
个人主页:手握风云
目录
[一、String 类型核心操作](#一、String 类型核心操作)
[1.1. 批量操作](#1.1. 批量操作)
[1.2. 内容追加](#1.2. 内容追加)
[1.3. 截取与替换](#1.3. 截取与替换)
[1.4. 防覆盖设置](#1.4. 防覆盖设置)
[1.5. 毫秒级过期](#1.5. 毫秒级过期)
[1.6. 原子数值增减](#1.6. 原子数值增减)
[二、List 类型核心操作](#二、List 类型核心操作)
[2.1. 基础左右增删](#2.1. 基础左右增删)
[2.2. 范围查询](#2.2. 范围查询)
[2.3. 阻塞弹出](#2.3. 阻塞弹出)
[2.4. 索引与插入](#2.4. 索引与插入)
[2.5. 长度统计](#2.5. 长度统计)
一、String 类型核心操作
Jedis 针对 Redis String 类型提供了一组常用字符串操作 API,覆盖批量读写、内容追加、截取替换、防覆盖设置、过期控制、原子数值增减等核心场景。
1.1. 批量操作
- mset:一次性设置多个 key-value 键值对。
- mget:一次性获取多个 key 对应的 value,返回值列表。
java
public static void test1(Jedis jedis) {
System.out.println("批量操作: mset / mget");
jedis.flushDB();
// 一次性设置多个 key-value
jedis.mset("user1", "Alice", "user2", "Bob");
System.out.println("设置多个 key-value 成功");
// 一次性获取多个 key 对应的 value
List<String> values = jedis.mget("user1", "user2", "user3");
System.out.println("获取结果: " + values);
System.out.println("======");
}

1.2. 内容追加
- append:向指定 key 的字符串末尾追加内容,获取后得到拼接后的完整字符串。
java
public static void test2(Jedis jedis) {
System.out.println("内容追加: append");
jedis.flushDB();
jedis.set("greeting", "Hello");
System.out.println("出事字符串: " + jedis.get("greeting"));
// 向末尾追加内容
long newLen = jedis.append("greeting", "World!");
System.out.println("追加后的长度: " + newLen);
System.out.println("追加后的内容: " + jedis.get("greeting") + "\n");
System.out.println("======");
}

1.3. 截取与替换
- getrange:按闭区间截取字符串的指定子串。
- setrange:从指定下标位置开始,替换字符串的部分内容。
java
public static void test3(Jedis jedis) {
System.out.println("截取与替换: getrange / setrange");
jedis.flushDB();
jedis.set("title", "RedisStringTutorial");
// 闭区间 [start, end] 截取
String subString = jedis.getrange("title", 0, 4);
System.out.println("截取的子串结果: " + subString);
// 从指定下标开始替换内容
jedis.setrange("title", 5, "Hash");
System.out.println("替换后的内容: " + jedis.get("title"));
System.out.println("======");
}

1.4. 防覆盖设置
- setnx:仅当 key 不存在时才设置值,设置成功返回 1,已存在则返回 0(不覆盖)。
java
public static void test4(Jedis jedis) {
System.out.println("防覆盖设置: setnx");
jedis.flushDB();
// 第一次设置,key 不存在
long ret1 = jedis.setnx("lock_resource", "locked_by_thread_1");
System.out.println("首次 setnx 结果: " + ret1 + " (1 表示成功设置)");
// 第二次设置,key 已存在
long ret2 = jedis.setnx("lock_resource", "locked_by_thread_2");
System.out.println("再次 setnx 结果: " + ret2 + " (0 表示 key 已存在,未覆盖)");
System.out.println("======");
}

1.5. 毫秒级过期
- psetex:设置键值的同时,指定毫秒级过期时间。
- pttl:查询 key 剩余的过期时间(毫秒)。
java
public static void test5(Jedis jedis) {
System.out.println("毫秒级过期: psetex / pttl");
jedis.flushDB();
// 设置键值对,并指定 5000 ms 后过期
jedis.psetex("temp_token", 5000L, "token_abc123");
// 查询剩余毫秒级过期时间
long pttl = jedis.pttl("temp_token");
System.out.println("剩余过期时间: " + pttl + "\n");
System.out.println("======");
}

1.6. 原子数值增减
- incr/decr:对数值型字符串执行 ±1 原子操作。
- incrby/decrby:按指定步长,对数值型字符串执行 ± 指定数值 原子操作。
java
public static void test6(Jedis jedis) {
System.out.println("原子数值增减: incr / decr / incrby / decrby");
jedis.flushDB();
jedis.set("page_view", "100");
// 自增 1
jedis.incr("page_view");
System.out.println("自增 1 之后: " + jedis.get("page_view"));
// 自减 1
jedis.decr("page_views");
System.out.println("自减 1 之后: " + jedis.get("page_views"));
// 自增指定数值
jedis.incrBy("page_views", 20);
System.out.println("自增 20 之后: " + jedis.get("page_views"));
// 自减指定数值
jedis.decrBy("page_views", 30);
System.out.println("自减 20 之后: " + jedis.get("page_views"));
System.out.println("======");
}

二、List 类型核心操作
Redis 列表为双向链表结构,基于 Jedis 实现的列表操作围绕左 / 右增删、范围查询、阻塞弹出、索引定位、指定位置插入、长度统计展开,核心方法及功能如下:
2.1. 基础左右增删
- lpush / lpop:lpush 从列表左侧批量添加元素,返回元素总数;lpop 从列表左侧弹出元素,列表为空时返回 null。
- rpush / rpop:rpush 从列表右侧批量添加元素,返回元素总数;rpop 从列表右侧弹出元素,列表为空时返回 null。
java
public static void test1(Jedis jedis) {
System.out.println("基础左右增删: lpush / lpop 和 rpush / rpop 操作");
jedis.flushDB();
String key = "list:basic";
// 从左侧批量添加
long lpushCount = jedis.lpush(key, "val1", "val2", "val3");
System.out.println("列表里面元素总数: " + lpushCount);
// 从左侧弹出元素
String lpopRet = jedis.lpop(key);
System.out.println("列表从左侧弹出元素: " + lpopRet);
// 从右侧批量添加
long rpushCount = jedis.rpush(key, "val4", "val5");
System.out.println("列表里面元素总数: " + rpushCount);
// 从右侧弹出元素
String rpopRet = jedis.rpop(key);
System.out.println("列表从右侧弹出元素: " + rpopRet);
System.out.println("======");
}

2.2. 范围查询
lrange:按闭区间索引获取列表元素,0 为起始、-1 为末尾,可查询全量数据。
java
public static void test2(Jedis jedis) {
System.out.println("范围查询: lrange 操作");
jedis.flushDB();
String key = "list:range";
jedis.rpush(key, "a", "b", "c", "d", "e");
// 查询全部数据
List<String> rangeList = jedis.lrange(key, 0, -1);
System.out.println("查询结果: " + rangeList);
System.out.println("======");
}

2.3. 阻塞弹出
blpop / brpop:阻塞式左 / 右弹出,超时时间设为 0 表示无限等待;返回 [key, value] 二元组,需通过新 Jedis 连接插入数据才能触发返回。
java
public static void test3(Jedis producerJedis) {
System.out.println("阻塞弹出: blpop / brpop");
producerJedis.flushDB();
String key = "list:blocking";
// 模拟延迟 1 秒后,通过新的 Jedis 连接插入数据
Thread t1 = new Thread(() -> {
try {
Thread.sleep(1_000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("生产者正在通过新连接 rpush 插入新数据...");
producerJedis.rpush(key, "wake_up");
});
JedisPool pool = new JedisPool("tcp://127.0.0.1:8888");
try (Jedis consumerJedis = pool.getResource()) {
consumerJedis.flushDB();
t1.start();
System.out.println("消费者正在通过新连接 blpop 阻塞弹出数据...");
List<String> ret = consumerJedis.blpop(0, key);
System.out.println("消费者阻塞弹出的数据: " + ret);
System.out.println("======");
}
}

2.4. 索引与插入
- lindex:获取列表指定索引的元素。
- linsert:在指定元素前(BEFORE)/ 后(AFTER)插入新元素,需通过 ListPosition 枚举指定位置。
java
public static void test4(Jedis jedis) {
System.out.println("索引与插入: lindex 与 linsert");
jedis.flushDB();
String key = "list:index_insert";
jedis.rpush(key, "item1", "item2", "item3");
// 获取指定索引的元素
String indexRet = jedis.lindex(key, 1);
System.out.println("索引为 1 的元素: " + indexRet);
// 在 "item2" 之前添加 "new_item1"
jedis.linsert(key, ListPosition.BEFORE, "item2", "new_item1");
// 在 "item2" 之后添加 "new_item2"
jedis.linsert(key, ListPosition.AFTER, "item2", "new_item2");
List<String> ret = jedis.lrange(key, 0, -1);
System.out.println("插入新数据后的结果: " + ret);
System.out.println("======");
}

2.5. 长度统计
- llen:查询列表的元素总个数。
java
public static void test5(Jedis jedis) {
System.out.println("长度统计: llen");
jedis.flushDB();
String key = "list:length";
jedis.rpush(key, "A", "B", "C", "D", "E");
long len = jedis.llen(key);
System.out.println("当前元素个数: " + len);
System.out.println("======");
}
