☰
Current Page
Main Menu
Home
Home
Editing
RedisHelper-guide
Edit
Preview
h1
h2
h3
default
Set your preferred keybinding
default
vim
emacs
markdown
Set this page's format to
AsciiDoc
Creole
Markdown
MediaWiki
Org-mode
Plain Text
RDoc
Textile
Rendering unavailable for
BibTeX
Pod
reStructuredText
Help 1
Help 1
Help 1
Help 2
Help 3
Help 4
Help 5
Help 6
Help 7
Help 8
Autosaved text is available. Click the button to restore it.
Restore Text
# 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 单机模式配置 ```properties #单机模式 redis.mode=single redis.host=127.0.0.1 redis.port=6379 redis.db=0 redis.password=your_password ``` #### 2.2.2 集群模式配置 ```properties #集群模式 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 哨兵模式配置 ```properties #哨兵模式 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 | 是 | Redis 模式:single/cluster/sentinel | | redis.host | String | 单机模式必填 | Redis 主机地址 | | redis.port | Integer | 单机模式必填 | Redis 端口 | | redis.cluster.nodes | String | 集群/哨兵模式必填 | 节点地址,逗号分隔 | | redis.master | String | 哨兵模式必填 | 哨兵主节点名称 | | redis.db | Integer | 否 | 数据库索引 | | redis.password | String | 否 | 认证密码 | | redis.timeout | Integer | 否 | 连接超时时间(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 推荐命名模式 ```java // 统一前缀定义 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 读取缓存 ```java /** * 读取缓存 * @param key 缓存key * @return 缓存返回值(Object类型) */ public static Object get(String key) ``` **使用示例**: ```java Object value = RedisHelper.get("user:1001"); if (value != null) { // 需要手动类型转换 } ``` #### 4.1.2 设置缓存 ```java /** * 设置缓存 * @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. **序列化机制**: ```java // 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 设置缓存(默认过期时间) ```java public static void set(String key, Object value) ``` **说明**: 调用`set(key, value, null)`,使用底层默认过期时间 ### 4.2 类型化缓存操作 #### 4.2.1 读取指定类型的缓存 ```java /** * 读取缓存并转换为指定BaseModel类型 * @param key 缓存key * @param c 模型class(必须是BaseModel的子类) * @return 缓存返回值(指定类型) */ public static <T> T get(String key, Class<? extends BaseModel> c) ``` **转换逻辑**: ```java if (obj instanceof Map) { return (T) copy(c, (Map) obj); // 调用copy方法创建BaseModel实例 } ``` #### 4.2.2 读取BaseModel列表缓存 ```java /** * 读取缓存并转换为BaseModel列表 * @param key 缓存key * @param c 模型class * @return BaseModel列表 */ public static <T> List<T> getArray(String key, Class<? extends BaseModel> c) ``` **转换逻辑**: ```java if (obj instanceof List) { return (List<T>) copys(c, (List) obj); // 批量转换 } ``` ### 4.3 字符串操作 #### 4.3.1 读取字符串 ```java public static String getString(String key) ``` #### 4.3.2 设置字符串 ```java 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 ```java public static <T> List<T> getList(String key) ``` #### 4.4.2 添加List ```java public static void addList(String key, List value, Long expired) public static void addList(String key, List value) ``` #### 4.4.3 删除List操作 ```java public static void removeList(String key, List value) // 移除指定元素 public static void deleteList(String key) // 删除整个List ``` ### 4.5 Hash哈希表操作 #### 4.5.1 读取操作 ```java 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 写入操作 ```java 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 删除操作 ```java public static String hDel(String key, String field) // 删除单个字段 public static Long hDelKeys(String key, String[] fields) // 删除多个字段 ``` ### 4.6 Set集合操作 #### 4.6.1 查询操作 ```java 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 修改操作 ```java 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 删除缓存 ```java public static void remove(String key) ``` #### 4.7.2 过期时间管理 ```java public static Boolean expire(String key, Long expired) // 设置过期时间 public static Boolean exists(String key) // 判断key是否存在 ``` ### 4.8 分布式锁 #### 4.8.1 加锁操作 ```java public static void lock(String key, Long timeout) // 阻塞式加锁 ``` #### 4.8.2 尝试加锁 ```java public static Boolean tryLock(String key, Long waitTime, Long leaseTime) ``` **参数说明**: - `waitTime`: 等待获取锁的最长时间(秒) - `leaseTime`: 锁的持有时间(秒) #### 4.8.3 解锁操作 ```java public static void unlock(String key) ``` #### 4.8.4 注意事项 - 如果leaseTime释放时间传固定的时间,锁不会自动续期,要确保释放时间足够大于业务逻辑处理时间,避免锁到期释放。 首先要考虑业务本身的执行时间,还要考虑因为网络延迟、系统负载高、数据量递增等原因可能会导致业务执行时间变长,适当增加锁的释放时间 - 如果希望锁自动续期,leaseTime释放时间传-1L - 锁的key会自动加上前缀 lock: #### 4.8.5 分布式锁示例 **阻塞式加锁示例:** ```java 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 单个对象转换 ```java private static <T extends BaseModel> T copy(Class<? extends BaseModel> modelClass, Map<String, Object> value) ``` **实现逻辑**: ```java BaseModel<?> ar = modelClass.newInstance(); // 反射创建实例 ar.putAll(value); // 复制属性 return (T) ar; ``` #### 4.9.2 批量对象转换 ```java 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缓存示例 ```java // 定义模型 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缓存示例 ```java // 存储列表 List<User> userList = Arrays.asList(user1, user2); RedisHelper.addList("user:online", userList, 1800L); // 读取列表 List<User> cachedList = RedisHelper.getList("user:online"); ``` ### 5.3 分布式锁示例 ```java 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结构存储
Uploading file...
Sidebar
[[_TOC_]]
Edit message:
Cancel