590 lines
16 KiB
Java
590 lines
16 KiB
Java
package com.cdzy.operations.utils;
|
||
|
||
import org.springframework.beans.factory.annotation.Autowired;
|
||
import org.springframework.beans.factory.annotation.Qualifier;
|
||
import org.springframework.data.redis.core.RedisTemplate;
|
||
import org.springframework.stereotype.Component;
|
||
|
||
import java.util.*;
|
||
import java.util.concurrent.TimeUnit;
|
||
import java.util.stream.Collectors;
|
||
|
||
/**
|
||
* @author attiya
|
||
* @since 2025-03-20
|
||
*/
|
||
@Component
|
||
public class RedisUtil {
|
||
|
||
private final RedisTemplate<String, Object> redisTemplate; // 默认数据库
|
||
private final RedisTemplate<String, Object> redisTemplateDb2; // 数据库2
|
||
|
||
@Autowired
|
||
public RedisUtil(
|
||
RedisTemplate<String, Object> redisTemplate,
|
||
@Qualifier("redisTemplateDb2") RedisTemplate<String, Object> redisTemplateDb2) {
|
||
this.redisTemplate = redisTemplate;
|
||
this.redisTemplateDb2 = redisTemplateDb2;
|
||
}
|
||
|
||
/**
|
||
* 数据库常量定义
|
||
*/
|
||
public static class Database {
|
||
public static final int DB1 = 1; // 业务数据(默认)
|
||
public static final int DB2 = 2; // 监控/调度数据
|
||
}
|
||
|
||
// 调度工单相关
|
||
public static final String BIKE_DISPATCH_ORDER_PREFIX = "bike:dispatch:order:";
|
||
|
||
//巡检工单
|
||
public static final String BIKE_INSPECTION_ORDER_PREFIX = "bike:inspection:order:";
|
||
|
||
// 车辆信息相关
|
||
public static final String BIKE_ECU_PREFIX = "bike:ecu:";
|
||
|
||
// 车辆多长时间无单生成调度工单
|
||
public static final String BIKE_NO_DOCUMENT_PREFIX = "bike:dispatch:nodocument:";
|
||
|
||
|
||
/**
|
||
* 错误消息常量
|
||
*/
|
||
public static class ErrorMessages {
|
||
public static final String UNSUPPORTED_DATABASE = "不支持的数据库索引: ";
|
||
}
|
||
|
||
/**
|
||
* 获取指定数据库的RedisTemplate
|
||
*/
|
||
private RedisTemplate<String, Object> getRedisTemplate(int database) {
|
||
return switch (database) {
|
||
case Database.DB1 -> redisTemplate;
|
||
case Database.DB2 -> redisTemplateDb2;
|
||
default -> throw new IllegalArgumentException(ErrorMessages.UNSUPPORTED_DATABASE + database);
|
||
};
|
||
}
|
||
|
||
/* ==================== 原有功能保持不变 ==================== */
|
||
|
||
/**
|
||
* 设置过期时间
|
||
*
|
||
* @param key 键
|
||
* @param timeout 超时时间
|
||
* @param unit 时间单位
|
||
*/
|
||
public Boolean expire(String key, long timeout, TimeUnit unit) {
|
||
return redisTemplate.expire(key, timeout, unit);
|
||
}
|
||
|
||
/**
|
||
* 获取过期时间
|
||
*
|
||
* @param key 键
|
||
* @param unit 时间单位
|
||
*/
|
||
public Long getExpire(String key, TimeUnit unit) {
|
||
return redisTemplate.getExpire(key, unit);
|
||
}
|
||
|
||
/**
|
||
* 判断key是否存在
|
||
*
|
||
* @param key 键
|
||
*/
|
||
public Boolean hasKey(String key) {
|
||
return redisTemplate.hasKey(key);
|
||
}
|
||
|
||
/**
|
||
* 删除key
|
||
*
|
||
* @param key 键
|
||
*/
|
||
public Boolean delete(String key) {
|
||
return redisTemplate.delete(key);
|
||
}
|
||
|
||
/* ------------------- String 相关操作 ------------------ */
|
||
|
||
/**
|
||
* 设置键值对
|
||
*
|
||
* @param key 键
|
||
* @param value 值
|
||
*/
|
||
public void set(String key, Object value) {
|
||
redisTemplate.opsForValue().set(key, value);
|
||
}
|
||
|
||
/**
|
||
* 设置键值对并设置过期时间
|
||
*
|
||
* @param key 键
|
||
* @param value 值
|
||
* @param timeout 过期时间
|
||
* @param unit 时间单位
|
||
*/
|
||
public void set(String key, Object value, long timeout, TimeUnit unit) {
|
||
redisTemplate.opsForValue().set(key, value, timeout, unit);
|
||
}
|
||
|
||
/**
|
||
* 获取值
|
||
*
|
||
* @param key 键
|
||
*/
|
||
public Object get(String key) {
|
||
return redisTemplate.opsForValue().get(key);
|
||
}
|
||
|
||
/**
|
||
* 自增操作(增量=1)
|
||
*
|
||
* @param key 键
|
||
*/
|
||
public Long increment(String key) {
|
||
return redisTemplate.opsForValue().increment(key);
|
||
}
|
||
|
||
/**
|
||
* 自增操作(指定增量)
|
||
*
|
||
* @param key 键
|
||
* @param delta 增量
|
||
*/
|
||
public Long increment(String key, long delta) {
|
||
return redisTemplate.opsForValue().increment(key, delta);
|
||
}
|
||
|
||
/* ------------------- Hash 相关操作 ------------------ */
|
||
|
||
/**
|
||
* 设置Hash键值对
|
||
*
|
||
* @param key 键
|
||
* @param hashKey Hash键
|
||
* @param value 值
|
||
*/
|
||
public void hSet(String key, String hashKey, Object value) {
|
||
redisTemplate.opsForHash().put(key, hashKey, value);
|
||
}
|
||
|
||
/**
|
||
* 批量设置Hash键值对
|
||
*
|
||
* @param key 键
|
||
* @param map 多个Hash键值对
|
||
*/
|
||
public void hSetAll(String key, Map<String, Object> map) {
|
||
redisTemplate.opsForHash().putAll(key, map);
|
||
}
|
||
|
||
/**
|
||
* 获取Hash值
|
||
*
|
||
* @param key 键
|
||
* @param hashKey Hash键
|
||
*/
|
||
public Object hGet(String key, String hashKey) {
|
||
return redisTemplate.opsForHash().get(key, hashKey);
|
||
}
|
||
|
||
/**
|
||
* 获取所有Hash键值对
|
||
*
|
||
* @param key 键
|
||
*/
|
||
public Map<Object, Object> hGetAll(String key) {
|
||
return redisTemplate.opsForHash().entries(key);
|
||
}
|
||
|
||
/**
|
||
* 删除Hash键
|
||
*
|
||
* @param key 键
|
||
* @param hashKeys Hash键集合
|
||
*/
|
||
public Long hDelete(String key, Object... hashKeys) {
|
||
return redisTemplate.opsForHash().delete(key, hashKeys);
|
||
}
|
||
|
||
/* ------------------- List 相关操作 ------------------ */
|
||
|
||
/**
|
||
* 左推入元素
|
||
*
|
||
* @param key 键
|
||
* @param value 值
|
||
*/
|
||
public Long lPush(String key, Object value) {
|
||
return redisTemplate.opsForList().leftPush(key, value);
|
||
}
|
||
|
||
/**
|
||
* 右推入元素
|
||
*
|
||
* @param key 键
|
||
* @param value 值
|
||
*/
|
||
public Long rPush(String key, Object value) {
|
||
return redisTemplate.opsForList().rightPush(key, value);
|
||
}
|
||
|
||
/**
|
||
* 获取列表范围
|
||
*
|
||
* @param key 键
|
||
* @param start 开始索引
|
||
* @param end 结束索引
|
||
*/
|
||
public List<Object> lRange(String key, long start, long end) {
|
||
return redisTemplate.opsForList().range(key, start, end);
|
||
}
|
||
|
||
/* ------------------- Set 相关操作 ------------------ */
|
||
|
||
/**
|
||
* 添加集合元素
|
||
*
|
||
* @param key 键
|
||
* @param values 值数组
|
||
*/
|
||
public Long sAdd(String key, Object... values) {
|
||
return redisTemplate.opsForSet().add(key, values);
|
||
}
|
||
|
||
/**
|
||
* 获取集合所有元素
|
||
*
|
||
* @param key 键
|
||
*/
|
||
public Set<Object> sMembers(String key) {
|
||
return redisTemplate.opsForSet().members(key);
|
||
}
|
||
|
||
/* ------------------- ZSet 相关操作 ------------------ */
|
||
|
||
/**
|
||
* 添加有序集合元素
|
||
*
|
||
* @param key 键
|
||
* @param value 值
|
||
* @param score 分数
|
||
*/
|
||
public Boolean zAdd(String key, Object value, double score) {
|
||
return redisTemplate.opsForZSet().add(key, value, score);
|
||
}
|
||
|
||
/**
|
||
* 获取有序集合范围
|
||
*
|
||
* @param key 键
|
||
* @param start 开始索引
|
||
* @param end 结束索引
|
||
*/
|
||
public Set<Object> zRange(String key, long start, long end) {
|
||
return redisTemplate.opsForZSet().range(key, start, end);
|
||
}
|
||
|
||
/* ------------------- 其他操作 ------------------ */
|
||
|
||
/**
|
||
* 获取匹配的键
|
||
*
|
||
* @param pattern 匹配模式
|
||
*/
|
||
public Set<String> keys(String pattern) {
|
||
return redisTemplate.keys(pattern);
|
||
}
|
||
|
||
/**
|
||
* 分布式锁:尝试获取锁
|
||
*
|
||
* @param key 锁键
|
||
* @param value 锁值
|
||
* @param timeout 超时时间
|
||
* @param unit 时间单位
|
||
*/
|
||
public Boolean tryLock(String key, Object value, long timeout, TimeUnit unit) {
|
||
return redisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit);
|
||
}
|
||
|
||
/**
|
||
* 释放锁
|
||
*
|
||
* @param key 锁键
|
||
*/
|
||
public Boolean releaseLock(String key) {
|
||
return redisTemplate.delete(key);
|
||
}
|
||
|
||
/* ==================== 新增:多数据库操作 ==================== */
|
||
|
||
/**
|
||
* 设置键值对到指定数据库
|
||
*/
|
||
public void set(int database, String key, Object value) {
|
||
getRedisTemplate(database).opsForValue().set(key, value);
|
||
}
|
||
|
||
/**
|
||
* 设置键值对到指定数据库并设置过期时间
|
||
*/
|
||
public void set(int database, String key, Object value, long timeout, TimeUnit unit) {
|
||
getRedisTemplate(database).opsForValue().set(key, value, timeout, unit);
|
||
}
|
||
|
||
/**
|
||
* 从指定数据库获取值
|
||
*/
|
||
public Object get(int database, String key) {
|
||
return getRedisTemplate(database).opsForValue().get(key);
|
||
}
|
||
|
||
/**
|
||
* 设置Hash键值对到指定数据库
|
||
*/
|
||
public void hSet(int database, String key, String hashKey, Object value) {
|
||
getRedisTemplate(database).opsForHash().put(key, hashKey, value);
|
||
}
|
||
|
||
/**
|
||
* 从指定数据库获取Hash值
|
||
*/
|
||
public Object hGet(int database, String key, String hashKey) {
|
||
return getRedisTemplate(database).opsForHash().get(key, hashKey);
|
||
}
|
||
|
||
/**
|
||
* 批量设置Hash键值对到指定数据库
|
||
*/
|
||
public void hSetAll(int database, String key, Map<String, Object> map) {
|
||
getRedisTemplate(database).opsForHash().putAll(key, map);
|
||
}
|
||
|
||
/**
|
||
* 从指定数据库获取所有Hash键值对
|
||
*/
|
||
public Map<Object, Object> hGetAll(int database, String key) {
|
||
return getRedisTemplate(database).opsForHash().entries(key);
|
||
}
|
||
|
||
/**
|
||
* 从指定数据库删除Hash键
|
||
*/
|
||
public Long hDelete(int database, String key, Object... hashKeys) {
|
||
return getRedisTemplate(database).opsForHash().delete(key, hashKeys);
|
||
}
|
||
|
||
/**
|
||
* 添加有序集合元素到指定数据库
|
||
*/
|
||
public Boolean zAdd(int database, String key, Object value, double score) {
|
||
return getRedisTemplate(database).opsForZSet().add(key, value, score);
|
||
}
|
||
|
||
/**
|
||
* 从指定数据库获取有序集合范围
|
||
*/
|
||
public Set<Object> zRange(int database, String key, long start, long end) {
|
||
return getRedisTemplate(database).opsForZSet().range(key, start, end);
|
||
}
|
||
|
||
/**
|
||
* 从指定数据库按分数范围获取有序集合
|
||
*/
|
||
public Set<Object> zRangeByScore(int database, String key, double min, double max) {
|
||
return getRedisTemplate(database).opsForZSet().rangeByScore(key, min, max);
|
||
}
|
||
|
||
/**
|
||
* 从指定数据库删除有序集合元素
|
||
*/
|
||
public Long zRemove(int database, String key, Object... values) {
|
||
return getRedisTemplate(database).opsForZSet().remove(key, values);
|
||
}
|
||
|
||
/**
|
||
* 删除指定数据库的key
|
||
*/
|
||
public Boolean delete(int database, String key) {
|
||
return getRedisTemplate(database).delete(key);
|
||
}
|
||
|
||
/**
|
||
* 判断指定数据库的key是否存在
|
||
*/
|
||
public Boolean hasKey(int database, String key) {
|
||
return getRedisTemplate(database).hasKey(key);
|
||
}
|
||
|
||
/**
|
||
* 设置指定数据库key的过期时间
|
||
*/
|
||
public Boolean expire(int database, String key, long timeout, TimeUnit unit) {
|
||
return getRedisTemplate(database).expire(key, timeout, unit);
|
||
}
|
||
|
||
/**
|
||
* 从指定数据库获取匹配的键
|
||
*/
|
||
public Set<String> keys(int database, String pattern) {
|
||
return getRedisTemplate(database).keys(pattern);
|
||
}
|
||
|
||
/* ==================== 新增:便捷方法 ==================== */
|
||
|
||
/**
|
||
* 数据库2专用:存储调度工单
|
||
*/
|
||
public void saveDispatchOrder(String orderId, Object orderData) {
|
||
set(Database.DB2, BIKE_DISPATCH_ORDER_PREFIX + orderId, orderData);
|
||
}
|
||
|
||
/**
|
||
* 数据库2专用:获取调度工单
|
||
*/
|
||
public Object getDispatchOrder(String orderId) {
|
||
return get(Database.DB2, BIKE_DISPATCH_ORDER_PREFIX + orderId);
|
||
}
|
||
|
||
/**
|
||
* 数据库2专用:存储调度工单并设置过期时间
|
||
*/
|
||
public void saveDispatchOrder(Long orderId, Object orderData, long timeout, TimeUnit unit) {
|
||
set(Database.DB2, BIKE_DISPATCH_ORDER_PREFIX + orderId, orderData, timeout, unit);
|
||
}
|
||
|
||
/**
|
||
* 数据库2专用:移除调度工单并设置过期时间
|
||
*/
|
||
public void deleteDispatchOrder(Long orderId) {
|
||
delete(Database.DB2, BIKE_DISPATCH_ORDER_PREFIX + orderId);
|
||
}
|
||
|
||
/**
|
||
* 数据库2专用:存储需要定期巡检车辆并设置过期时间
|
||
*/
|
||
public void saveInspectionOrder(String bikeCode, Object bikeInfo, long timeout, TimeUnit unit) {
|
||
set(Database.DB2, BIKE_INSPECTION_ORDER_PREFIX + bikeCode, bikeInfo, timeout, unit);
|
||
}
|
||
|
||
/**
|
||
* 数据库2专用:移除调度工单并设置过期时间
|
||
*/
|
||
public void deleteInspectionOrder(String bikeCode) {
|
||
delete(Database.DB2, BIKE_INSPECTION_ORDER_PREFIX + bikeCode);
|
||
}
|
||
|
||
/**
|
||
* 数据库2专用:分布式锁(针对巡检任务)
|
||
*/
|
||
public Boolean tryInspectionLock(String lockKey, Object value, long timeout, TimeUnit unit) {
|
||
return getRedisTemplate(Database.DB2).opsForValue().setIfAbsent(lockKey, value, timeout, unit);
|
||
}
|
||
|
||
/**
|
||
* 数据库2专用:释放调度锁
|
||
*/
|
||
public Boolean releaseInspectionLock(String lockKey) {
|
||
return delete(Database.DB2, lockKey);
|
||
}
|
||
|
||
/**
|
||
* 数据库2专用:分布式锁(针对调度任务)
|
||
*/
|
||
public Boolean tryDispatchLock(String lockKey, Object value, long timeout, TimeUnit unit) {
|
||
return getRedisTemplate(Database.DB2).opsForValue().setIfAbsent(lockKey, value, timeout, unit);
|
||
}
|
||
|
||
/**
|
||
* 数据库2专用:释放调度锁
|
||
*/
|
||
public Boolean releaseDispatchLock(String lockKey) {
|
||
return delete(Database.DB2, lockKey);
|
||
}
|
||
|
||
|
||
/**
|
||
* 数据库2专用:存储 车辆多长时间无单生成调度工单 并设置过期时间
|
||
*/
|
||
public void saveNoDocument(String bikeCode, Object orderData, long timeout, TimeUnit unit) {
|
||
set(Database.DB2, BIKE_NO_DOCUMENT_PREFIX + bikeCode, orderData, timeout, unit);
|
||
}
|
||
|
||
/**
|
||
* 数据库2专用:删除 车辆多长时间无单生成调度工单
|
||
*/
|
||
public void deleteNoDocument(String bikeCode) {
|
||
delete(Database.DB2, BIKE_NO_DOCUMENT_PREFIX + bikeCode);
|
||
}
|
||
|
||
/**
|
||
* 数据库2专用:分布式锁(针对调度任务)
|
||
*/
|
||
public Boolean tryNoDocumentLock(String lockKey, Object value, long timeout, TimeUnit unit) {
|
||
return getRedisTemplate(Database.DB2).opsForValue().setIfAbsent(lockKey, value, timeout, unit);
|
||
}
|
||
|
||
|
||
/**
|
||
* 数据库2专用:存储中控信息
|
||
*/
|
||
public void saveEcu(String ecuSn, Object ecuData) {
|
||
set(Database.DB2, BIKE_ECU_PREFIX + ecuSn, ecuData);
|
||
}
|
||
|
||
/**
|
||
* 数据库2专用:获取中控信息
|
||
*/
|
||
public Object getEcu(String ecuSn) {
|
||
return get(Database.DB2, BIKE_ECU_PREFIX + ecuSn);
|
||
}
|
||
|
||
/**
|
||
* 批量获取ECU信息(基于已知的SN列表)
|
||
*
|
||
* @param ecuSnList ECU序列号列表
|
||
* @return ECU信息列表,顺序与输入列表对应
|
||
*/
|
||
public List<Object> batchGetEcu(List<String> ecuSnList) {
|
||
List<String> keys = ecuSnList.stream()
|
||
.map(sn -> BIKE_ECU_PREFIX + sn)
|
||
.collect(Collectors.toList());
|
||
|
||
return getRedisTemplate(Database.DB2).opsForValue().multiGet(keys);
|
||
}
|
||
|
||
/**
|
||
* 批量获取ECU信息(基于已知的SN列表)
|
||
*
|
||
* @param ecuSnList ECU序列号列表
|
||
* @return Map<ECU_SN, ECU_Data> 映射关系
|
||
*/
|
||
public Map<String, Object> batchGetEcuWithMap(List<String> ecuSnList) {
|
||
if (ecuSnList == null || ecuSnList.isEmpty()) {
|
||
return Collections.emptyMap();
|
||
}
|
||
|
||
// 构建完整的Redis键列表
|
||
List<String> keys = ecuSnList.stream()
|
||
.map(sn -> BIKE_ECU_PREFIX + sn)
|
||
.collect(Collectors.toList());
|
||
|
||
// 批量获取值
|
||
List<Object> values = getRedisTemplate(Database.DB2).opsForValue().multiGet(keys);
|
||
|
||
// 构建映射关系
|
||
Map<String, Object> result = new LinkedHashMap<>();
|
||
for (int i = 0; i < ecuSnList.size(); i++) {
|
||
String sn = ecuSnList.get(i);
|
||
Object value = (values != null && i < values.size()) ? values.get(i) : null;
|
||
result.put(sn, value);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
} |