liusuyi
2026-01-19 3c8d6b8e60f02b9a40fc5acd4dc6c34a6b594eb6
ard-common/src/main/java/com/ard/common/core/redis/RedisOpsUtils.java
@@ -2,12 +2,15 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Set;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
@@ -261,4 +264,50 @@
    public static Double zIncrement(String key, Object value, double delta) {
        return redisTemplate.opsForZSet().incrementScore(key, value, delta);
    }
    /**
     * 批量读取所有相关键值对
     * @return 完整键 -> 值的映射
     */
    public static Map<Object, Object> getAllData(String keyPrefix) {
        Map<Object, Object> resultMap = new HashMap<>();
        // 1. 用SCAN命令匹配前缀,获取所有相关键
        List<Object> keys = redisTemplate.execute((RedisCallback<List<Object>>) connection -> {
            List<Object> keyList = new ArrayList<>();
            // 构造匹配模式:前缀 + "*"
            ScanOptions options = ScanOptions.scanOptions()
                    .match(keyPrefix)  // 匹配所有带前缀的键
                    .count(100)  // 每次迭代最多返回100个键(可根据实际调整)
                    .build();
            // try-with-resources自动关闭Cursor,避免资源泄漏
            try (Cursor<byte[]> cursor = connection.scan(options)) {
                while (cursor.hasNext()) {
                    byte[] keyBytes = cursor.next();
                    String key = new String(keyBytes, StandardCharsets.UTF_8);
                    keyList.add(key);
                }
            } catch (Exception e) {
                throw new RuntimeException("Redis SCAN命令执行失败", e);
            }
            return keyList;
        });
        // 2. 批量获取值(减少网络请求)
        if (!CollectionUtils.isEmpty(keys)) {
            List<Object> values = redisTemplate.opsForValue().multiGet(keys);
            // 3. 组装键值对
            for (int i = 0; i < keys.size(); i++) {
                Object key = keys.get(i);
                Object value = values.get(i);
                if (value != null) {
                    resultMap.put(key, value);
                }
            }
        }
        return resultMap;
    }
}