模板代码
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;/*** Redis 缓存服务(仅字符串 + Hash(Map))。** <p>基于 StringRedisTemplate:key/value 都是字符串;Map 使用 Redis Hash 存储。</p>*/
@Service
@SuppressWarnings("null")
public class RedisCacheService {private final StringRedisTemplate stringRedisTemplate;public RedisCacheService(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate = stringRedisTemplate;}// ========================= String =========================/*** 写入字符串(不设置过期时间)。** @param key Redis key* @param value 字符串值*/public void setString(String key, String value) {stringRedisTemplate.opsForValue().set(key, value);}/*** 写入字符串,并可选设置过期时间。** <p>当 ttl 为 null / 0 / 负数时,等同于不过期写入。</p>** @param key Redis key* @param value 字符串值* @param ttl 过期时间*/public void setString(String key, String value, Duration ttl) {if (ttl == null || ttl.isZero() || ttl.isNegative()) {stringRedisTemplate.opsForValue().set(key, value);return;}stringRedisTemplate.opsForValue().set(key, value, ttl);}/*** 读取字符串。** @param key Redis key* @return 字符串值;不存在返回 null*/public String getString(String key) {return stringRedisTemplate.opsForValue().get(key);}// ========================= Hash(Map) =========================/*** 写入 Map(以 Redis Hash 存储),不设置过期时间。** <p>map 为 null/空时不做任何操作。</p>** @param key Redis key(hash key)* @param map field/value 集合*/public void putMapAll(String key, Map<String, String> map) {if (map == null || map.isEmpty()) {return;}stringRedisTemplate.opsForHash().putAll(key, map);}/*** 写入 Map(以 Redis Hash 存储),并可选设置过期时间。** <p>当 ttl 为 null / 0 / 负数时,不会设置过期时间。</p>** @param key Redis key(hash key)* @param map field/value 集合* @param ttl 过期时间*/public void putMapAll(String key, Map<String, String> map, Duration ttl) {putMapAll(key, map);expire(key, ttl);}/*** 写入 Hash 的单个字段(不设置过期时间)。** @param key Redis key(hash key)* @param field hash field* @param value 字符串值*/public void putMapField(String key, String field, String value) {stringRedisTemplate.opsForHash().put(key, field, value);}/*** 写入 Hash 的单个字段,并可选设置过期时间。** <p>当 ttl 为 null / 0 / 负数时,不会设置过期时间。</p>** @param key Redis key(hash key)* @param field hash field* @param value 字符串值* @param ttl 过期时间*/public void putMapField(String key, String field, String value, Duration ttl) {putMapField(key, field, value);expire(key, ttl);}/*** 读取 Hash 的单个字段。** @param key Redis key(hash key)* @param field hash field* @return 字段值;不存在返回 null*/public String getMapField(String key, String field) {Object v = stringRedisTemplate.opsForHash().get(key, field);return v == null ? null : String.valueOf(v);}/*** 读取 Hash 的所有字段(等价于 HGETALL)。** <p>当 key 不存在或 hash 为空时返回空 Map。</p>** @param key Redis key(hash key)* @return field/value 集合*/public Map<String, String> getMapAll(String key) {Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries(key);if (entries == null || entries.isEmpty()) {return Collections.emptyMap();}Map<String, String> res = new HashMap<>(entries.size());for (Map.Entry<Object, Object> e : entries.entrySet()) {if (e.getKey() == null) {continue;}res.put(String.valueOf(e.getKey()), Objects.toString(e.getValue(), null));}return res;}// ========================= Common =========================/*** 删除指定 key。** @param key Redis key* @return 删除成功返回 true;key 不存在通常返回 false*/public boolean delete(String key) {Boolean ok = stringRedisTemplate.delete(key);return Boolean.TRUE.equals(ok);}/*** 设置过期时间(TTL)。** <p>当 ttl 为 null / 0 / 负数时,不做设置并返回 false。</p>** @param key Redis key* @param ttl 过期时间* @return 设置成功返回 true*/public boolean expire(String key, Duration ttl) {if (ttl == null || ttl.isZero() || ttl.isNegative()) {return false;}Boolean ok = stringRedisTemplate.expire(key, ttl.toMillis(), TimeUnit.MILLISECONDS);return Boolean.TRUE.equals(ok);}
}
使用示例:
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;import java.time.Duration;
import java.util.Map;@RestController
@RequestMapping("/demo/redis")
@RequiredArgsConstructor
@Tag(name = "Redis 示例", description = "字符串与 Hash(Map) 的存取示例(基于 StringRedisTemplate)")
public class RedisDemoController {private final RedisCacheService redisCacheService;@PostMapping("/string/set")@Operation(summary = "写入字符串", description = "value 存为 string;ttlSeconds 不填/<=0 表示不过期")public Result<Void> setString(@RequestBody RedisStringPutRequest req) {Duration ttl = toTtl(req.getTtlSeconds());if (ttl == null) {redisCacheService.setString(req.getKey(), req.getValue());} else {redisCacheService.setString(req.getKey(), req.getValue(), ttl);}return Result.success();}@GetMapping("/string/get")@Operation(summary = "读取字符串")public Result<String> getString(@RequestParam("key") String key) {return Result.success(redisCacheService.getString(key));}@PostMapping("/hash/putAll")@Operation(summary = "写入 Map(putAll)", description = "map 存为 hash;ttlSeconds 不填/<=0 表示不过期")public Result<Void> putAll(@RequestBody RedisMapPutRequest req) {Duration ttl = toTtl(req.getTtlSeconds());if (ttl == null) {redisCacheService.putMapAll(req.getKey(), req.getMap());} else {redisCacheService.putMapAll(req.getKey(), req.getMap(), ttl);}return Result.success();}@GetMapping("/hash/entries")@Operation(summary = "读取 Map(entries)")public Result<Map<String, String>> entries(@RequestParam("key") String key) {return Result.success(redisCacheService.getMapAll(key));}@PostMapping("/hash/put")@Operation(summary = "写入 hash 单个 field", description = "field/value 存为 hash;ttlSeconds 不填/<=0 表示不修改过期时间")public Result<Void> putField(@RequestParam("key") String key,@RequestParam("field") String field,@RequestParam("value") String value,@RequestParam(value = "ttlSeconds", required = false) Long ttlSeconds) {Duration ttl = toTtl(ttlSeconds);if (ttl == null) {redisCacheService.putMapField(key, field, value);} else {redisCacheService.putMapField(key, field, value, ttl);}return Result.success();}@GetMapping("/hash/get")@Operation(summary = "读取 hash 单个 field")public Result<String> getField(@RequestParam("key") String key,@RequestParam("field") String field) {return Result.success(redisCacheService.getMapField(key, field));}@DeleteMapping("/del")@Operation(summary = "删除 key")public Result<Boolean> del(@RequestParam("key") String key) {return Result.success(redisCacheService.delete(key));}private Duration toTtl(Long ttlSeconds) {if (ttlSeconds == null || ttlSeconds <= 0) {return null;}return Duration.ofSeconds(ttlSeconds);}
}
