590 lines
16 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}