RedisHelper 缓存工具类开发文档

1. 概述

1.1 简介

RedisHelper 是基于 Redis 的缓存工具类,为 Java 应用提供统一的缓存操作接口。支持单机、集群和哨兵三种 Redis 部署模式,提供 String、List、Set、Hash 等数据结构的操作,以及分布式锁功能。

1.2 核心特性

  • ✅ 支持 Redis 单机、集群、哨兵模式
  • ✅ 提供多种数据结构的封装操作
  • ✅ 内置分布式锁实现
  • ✅ 支持自动续期和过期时间设置
  • ✅ 线程安全的缓存操作

2. 环境配置

2.1 依赖配置

确保项目中已引入 sie-iidp-cache App

2.2 配置文件

application-dev.properties 中配置 Redis 连接:

2.2.1 单机模式配置

#单机模式
redis.mode=single
redis.host=127.0.0.1
redis.port=6379
redis.db=0
redis.password=your_password

2.2.2 集群模式配置

#集群模式
redis.mode=cluster
#多个节点以英文逗号分隔,请勿输入空格
redis.cluster.nodes=127.0.0.1:7000,127.0.0.1:7001,127.0.0.1:7002
#集群节点扫描间隔,单位为毫秒
redis.cluster.scanInterval=2000
redis.db=0
redis.password=

2.2.3 哨兵模式配置

#哨兵模式
redis.mode=sentinel
#哨兵模式主节点名称配置
redis.master=mymaster
#多个节点以英文逗号分隔,请勿输入空格,这里用哨兵的端口
redis.cluster.nodes=127.0.0.1:26379,127.0.0.1:26380,127.0.0.1:26381
#集群节点扫描间隔,单位为毫秒
redis.cluster.scanInterval=2000
redis.db=0
redis.password=

2.3 参数说明

| 参数名 | 类型 | 必填 | 默认值 | 说明 | | ——————- | ——- | —————– | ——— | ———————————– | | redis.mode | String | 是 | single | Redis 模式:single/cluster/sentinel | | redis.host | String | 单机模式必填 | 127.0.0.1 | Redis 主机地址 | | redis.port | Integer | 单机模式必填 | 6379 | Redis 端口 | | redis.cluster.nodes | String | 集群/哨兵模式必填 | - | 节点地址,逗号分隔 | | redis.master | String | 哨兵模式必填 | - | 哨兵主节点名称 | | redis.db | Integer | 否 | 0 | 数据库索引 | | redis.password | String | 否 | - | 认证密码 | | redis.timeout | Integer | 否 | 2000 | 连接超时时间(ms) | | | | | | |

3. 命名规范

3.1 Key 命名规范

  1. 格式要求:使用英文冒号 : 作为分隔符
  2. 命名结构应用名:模块名:业务名:唯一标识
  3. 示例
    • newSdkApp:User:Session:userId_001
    • newSdkApp:Product:Cache:category_001
    • newSdkApp:Order:Lock:order_1001

3.2 推荐命名模式

// 统一前缀定义
public interface CacheKeys {
    String APP_PREFIX = "newSdkApp";
    
    // 用户模块
    String USER_SESSION = APP_PREFIX + ":User:Session:";
    String USER_ONLINE = APP_PREFIX + ":User:Online";
    String USER_INFO = APP_PREFIX + ":User:Info:";
    
    // 产品模块
    String PRODUCT_CACHE = APP_PREFIX + ":Product:Cache:";
    String PRODUCT_LIST = APP_PREFIX + ":Product:List:";
    
    // 订单模块
    String ORDER_LOCK = APP_PREFIX + ":Order:Lock:";
    String ORDER_CACHE = APP_PREFIX + ":Order:Cache:";
    
    // 系统配置
    String SYS_CONFIG = APP_PREFIX + ":Sys:Config:";
}

4. API 参考手册

● 类名: com.sie.snest.sdk.cache.RedisHelper ● 类型: 静态工具类 ● 功能: 提供统一的Redis缓存操作接口

4.1 基础缓存操作

4.1.1 读取缓存

/**
 * 读取缓存
 * @param key 缓存key
 * @return 缓存返回值(Object类型)
 */
public static Object get(String key)

使用示例:

Object value = RedisHelper.get("user:1001");
if (value != null) {
    // 需要手动类型转换
}

4.1.2 设置缓存

/**
 * 设置缓存
 * @param key     缓存key
 * @param value   缓存值
 * @param expired 缓存过期时间,单位为秒(-1永久)
 */
public static void set(String key, Object value, Long expired)

特性说明:

  1. 自动类型转换:
    • 当value是BaseModel类型时,自动转换为Map存储
    • 当value是List<BaseModel>类型时,自动转换为List<Map>存储
    • 其他类型直接存储
  2. 序列化机制:
// BaseModel处理流程
if (value instanceof BaseModel) {
    v = JSON.parseObject(JSON.toJSONString(value), Map.class);
}
// List<BaseModel>处理流程  
if (value instanceof List && 列表第一个元素是BaseModel) {
    v = JSON.parseArray(JSONObject.toJSONString(value), Map.class);
}

4.1.3 设置缓存(默认过期时间)

public static void set(String key, Object value)

说明: 调用set(key, value, null),使用底层默认过期时间

4.2 类型化缓存操作

4.2.1 读取指定类型的缓存

/**
 * 读取缓存并转换为指定BaseModel类型
 * @param key 缓存key
 * @param c   模型class(必须是BaseModel的子类)
 * @return 缓存返回值(指定类型)
 */
public static <T> T get(String key, Class<? extends BaseModel> c)

转换逻辑:

if (obj instanceof Map) {
    return (T) copy(c, (Map) obj);  // 调用copy方法创建BaseModel实例
}

4.2.2 读取BaseModel列表缓存

/**
 * 读取缓存并转换为BaseModel列表
 * @param key 缓存key
 * @param c   模型class
 * @return BaseModel列表
 */
public static <T> List<T> getArray(String key, Class<? extends BaseModel> c)

转换逻辑:

if (obj instanceof List) {
    return (List<T>) copys(c, (List) obj);  // 批量转换
}

4.3 字符串操作

4.3.1 读取字符串

public static String getString(String key)

4.3.2 设置字符串

public static void setString(String key, String value, Long expired)
public static void setString(String key, String value)

4.4 List列表操作

4.4.1 获取List

public static <T> List<T> getList(String key)

4.4.2 添加List

public static void addList(String key, List value, Long expired)
public static void addList(String key, List value)

4.4.3 删除List操作

public static void removeList(String key, List value)  // 移除指定元素
public static void deleteList(String key)              // 删除整个List

4.5 Hash哈希表操作

4.5.1 读取操作

public static String hGet(String key, String field)                    // 获取单个字段
public static Map<String, String> hMGet(String key, Set<String> field) // 获取多个字段
public static Map<String, String> hGetAll(String key)                  // 获取所有字段
public static Integer hLen(String key)                                 // 获取字段数量
public static Set<String> hKeys(String key)                            // 获取所有字段名

4.5.2 写入操作

public static void hSetAll(String key, Map<String, String> value, Long expired)
public static void hSetAll(String key, Map<String, String> value)
public static String hSet(String key, String field, String value, Long expired)
public static String hSet(String key, String field, String value)

4.5.3 删除操作

public static String hDel(String key, String field)     // 删除单个字段
public static Long hDelKeys(String key, String[] fields) // 删除多个字段

4.6 Set集合操作

4.6.1 查询操作

public static Boolean sExists(String key)                     // 判断Set是否存在
public static Boolean sIsMember(String key, String field)     // 判断是否为成员
public static Integer sCard(String key)                      // 获取成员数量
public static Set<String> sMembers(String key)               // 获取所有成员

4.6.2 修改操作

public static Boolean sAdd(String key, String field, Long expired)    // 添加单个成员
public static Boolean sAdd(String key, String field)
public static Boolean sAddAll(String key, Collection<String> field, Long expired) // 批量添加
public static Boolean sAddAll(String key, Collection<String> field)
public static Boolean sRemove(String key, String field)               // 移除成员

4.7 缓存管理

4.7.1 删除缓存

public static void remove(String key)

4.7.2 过期时间管理

public static Boolean expire(String key, Long expired)  // 设置过期时间
public static Boolean exists(String key)                // 判断key是否存在

4.8 分布式锁

4.8.1 加锁操作

public static void lock(String key, Long timeout)  // 阻塞式加锁

4.8.2 尝试加锁

public static Boolean tryLock(String key, Long waitTime, Long leaseTime)

参数说明:

  • waitTime: 等待获取锁的最长时间(秒)
  • leaseTime: 锁的持有时间(秒)

4.8.3 解锁操作

public static void unlock(String key)

4.8.4 注意事项

  • 如果leaseTime释放时间传固定的时间,锁不会自动续期,要确保释放时间足够大于业务逻辑处理时间,避免锁到期释放。 首先要考虑业务本身的执行时间,还要考虑因为网络延迟、系统负载高、数据量递增等原因可能会导致业务执行时间变长,适当增加锁的释放时间
  • 如果希望锁自动续期,leaseTime释放时间传-1L
  • 锁的key会自动加上前缀 lock:

4.8.5 分布式锁示例

阻塞式加锁示例:

public static void lockDemo() {
        Boolean isLocked=false;
        try {
            // 加锁,堵塞线程,加锁600秒后自动释放
            RedisHelper.lock("myLock",600L);
            isLocked=true;
            System.out.println("成功获取锁,执行业务逻辑...");
        } catch (Exception e) {
            // 获取锁失败
            e.printStackTrace();
        } finally {
            // 释放锁
            if(isLocked){
                RedisHelper.unlock("myLock");
                System.out.println("锁已释放");
            }
        }
    }

尝试加锁示例:

public static void tryLockDemo() {
        Boolean isLocked=false;
        try {
            // 尝试加锁,最多等待100秒,加锁600秒后自动释放
            isLocked = RedisHelper.tryLock("mylock",100L, 600L);
            if (isLocked) {
                // 成功获取锁,执行业务逻辑
                System.out.println("成功获取锁,执行业务逻辑...");
            } else {
                // 获取锁失败
                System.out.println("获取锁失败,可能有其他线程持有锁");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 释放锁
            if(isLocked){
                RedisHelper.unlock("mylock");
                System.out.println("锁已释放");
            }
        }
    }

4.9 内部辅助方法

4.9.1 单个对象转换

private static <T extends BaseModel> T copy(Class<? extends BaseModel> modelClass, 
                                           Map<String, Object> value)

实现逻辑:

BaseModel<?> ar = modelClass.newInstance();  // 反射创建实例
ar.putAll(value);                           // 复制属性
return (T) ar;

4.9.2 批量对象转换

private static <T> List<T> copys(Class<? extends BaseModel> modelClass, 
                                List<Map<String, Object>> values)

实现逻辑: 遍历列表,对每个Map调用copy方法转换

4.9.3. BaseModel使用规范

  1. 存储时: BaseModel会自动转换为Map存储

  2. 读取时: 使用get(String key, Class<T> c)方法可自动转换回BaseModel

  3. 列表读取: 使用getArray(String key, Class<T> c)方法

5. 典型使用示例

5.1 BaseModel缓存示例

// 定义模型
public class User extends BaseModel<User> {
    private String id;
    private String name;
    // getter/setter省略
}

// 存储用户
User user = new User();
user.setId("1001");
user.setName("张三");
RedisHelper.set("user:1001", user, 3600L);  // 自动转换为Map存储

// 读取用户
User cachedUser = RedisHelper.get("user:1001", User.class);  // 自动转换回User对象

5.2 List缓存示例

// 存储列表
List<User> userList = Arrays.asList(user1, user2);
RedisHelper.addList("user:online", userList, 1800L);

// 读取列表
List<User> cachedList = RedisHelper.getList("user:online");

5.3 分布式锁示例


public static void tryLockDemo() {
        Boolean isLocked=false;
        try {
            // 尝试加锁,最多等待100秒,加锁600秒后自动释放
            isLocked = RedisHelper.tryLock("mylock",100L, 600L);
            if (isLocked) {
                // 成功获取锁,执行业务逻辑
                System.out.println("成功获取锁,执行业务逻辑...");
            } else {
                // 获取锁失败
                System.out.println("获取锁失败,可能有其他线程持有锁");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 释放锁
            if(isLocked){
                RedisHelper.unlock("mylock");
                System.out.println("锁已释放");
            }
        }
    }

6. 常见问题

6.1 类型转换失败

问题: 使用get(key, Class<T> c)但缓存中存储的不是BaseModel 解决: 先使用get(key)检查类型,或确保存储时使用BaseModel

6.2 序列化异常

问题: 存储非BaseModel的复杂对象 解决: 自行处理序列化,或转换为Map结构存储