StringRedisTemplate与RedisTemplate区别点
- 两者的关系是StringRedisTemplate继承RedisTemplate。
- 两者的数据是不共通的;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据,RedisTemplate只能管理RedisTemplate中的数据。
- RedisTemplate使用的是JdkSerializationRedisSerializer序列化类,存入数据会将数据先序列化成字节数组然后在存入Redis数据库。 StringRedisTemplate使用的是StringRedisSerializer序列化类
- 当redis数据库里面本来存的是字符串数据或者要存取的数据就是字符串类型数据的时候,那么使用StringRedisTemplate即可。但是如果你的数据是复杂的对象类型,而取出的时候又不想做任何的数据转换,直接从Redis里面取出一个对象,那么使用RedisTemplate是更好的选择。
- redisTemplate 中存取数据都是字节数组。当redis中存入的数据是可读形式而非字节数组时,使用redisTemplate取值的时候会无法获取导出数据,获得的值为null。可以使用 StringRedisTemplate 试试
RedisTemplate中定义了5种数据结构操作:
redisTemplate.opsForValue(); //操作字符串
redisTemplate.opsForHash(); //操作hash
redisTemplate.opsForList(); //操作list
redisTemplate.opsForSet(); //操作set
redisTemplate.opsForZSet(); //操作有序set
StringRedisTemplate常用操作
// 向redis里存入数据和设置缓存时间
stringRedisTemplate.opsForValue().set("test", "100", 60*10, TimeUnit.SECONDS);
// val做-1操作
stringRedisTemplate.boundValueOps("test").increment(-1);
// 根据key获取缓存中的val
stringRedisTemplate.opsForValue().get("test")
// val + 1
stringRedisTemplate.boundValueOps("test").increment(1);
// 根据key获取过期时间
stringRedisTemplate.getExpire("test")
// 根据key获取过期时间并换算成指定单位
stringRedisTemplate.getExpire("test",TimeUnit.SECONDS);
// 根据key删除缓存
stringRedisTemplate.delete("test");
// 检查key是否存在,返回boolean值
stringRedisTemplate.hasKey("546545");
// 向指定key中存放set集合
stringRedisTemplate.opsForSet().add("red_123`在这里插入代码片`", "1", "2", "3");
// 设置过期时间
stringRedisTemplate.expire("red_123", 1000 , TimeUnit.MILLISECONDS);
// 根据key查看集合中是否存在指定数据
stringRedisTemplate.opsForSet().isMember("red_123", "1");
// 根据key获取set集合
stringRedisTemplate.opsForSet().members("red_123");
基于StringRedisTemplate封装一个缓存工具类,满足下列需求:
- 方法1:将任意Java对象序列化为json并存储在string类型的key中,并且可以设置TTL过期时间
- 方法2:将任意Java对象序列化为json并存储在string类型的key中,并且可以设置逻辑过期时间,用于处理缓存击穿问题
- 方法3:根据指定的key查询缓存,并反序列化为指定类型,利用缓存空值的方式解决缓存穿透问题
- 方法4:根据指定的key查询缓存,并反序列化为指定类型,需要利用逻辑过期解决缓存击穿问题
以下封装涉及到了缓存穿透与缓存击穿的解决方案,如果对两者不熟悉,可以看看我的另一篇博客了解一下这些解决方案:数据库面试题——redis缓存穿透、缓存击穿与缓存雪崩
依赖:
cn.hutool
hutool-all
5.7.17
封装:
@Component
@Slf4j
public class RedisUtils {
@Autowired
private static RedisTemplate redisTemplate;
private final StringRedisTemplate stringRedisTemplate;
// 防止缓存穿透而设置的空值的过期时间
private final Long CACHE_NULL_TTL = 2L;
// 防止缓存穿透而设置的空值的过期时间的单位
private final TimeUnit CACHE_UNIT = TimeUnit.MINUTES;
// 互斥锁
private final String LOCK_APP_KEY = "lock:app:";
private static final ExecutorService CACHE_REBUILD_EXECUTOR = Executors.newFixedThreadPool(10);
public RedisUtils(StringRedisTemplate stringRedisTemplate) {
this.stringRedisTemplate = stringRedisTemplate;
}
// =============================common============================
public boolean expire(String key, long time) {
if (time <= 0) return false;
redisTemplate.expire(key, time, TimeUnit.SECONDS);
return true;
}
public Long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
public Long getExpire(String key, TimeUnit unit) {
return redisTemplate.getExpire(key, unit);
}
public boolean hasKey(String key) {
return Boolean.TRUE.equals(redisTemplate.hasKey(key));
}
public boolean del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(Arrays.asList(key));
}
return true;
}
return false;
}
public boolean DelByPrefix(String prefix) {
Set keys = redisTemplate.keys(prefix + "*");
if(Objects.nonNull(keys)) {
redisTemplate.delete(keys);
return true;
}
return false;
}
// ============================String=============================
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
log.error("缓存写入错误!key:{},value:{},错误信息:{}", key, value, e.getMessage());
return false;
}
}
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
log.error("缓存写入错误!key:{},value:{},time:{},错误信息:{}", key, value, time, e.getMessage());
return false;
}
}
public Long incr(String key) {
return redisTemplate.opsForValue().increment(key, 1);
}
public Long incr(String key, long step) {
return redisTemplate.opsForValue().increment(key, step);
}
public Long decr(String key) {
return redisTemplate.opsForValue().increment(key, -1);
}
public Long decr(String key, long step) {
return redisTemplate.opsForValue().increment(key, -step);
}
// ================================Map=================================
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
public Map
如果有兴趣了解更多相关内容,欢迎来我的个人网站看看:瞳孔的个人空间