redisTemplate.opsForValue().get(key)取出空值
时间: 2024-03-27 18:28:32 浏览: 244
如果redisTemplate.opsForValue().get(key)返回了空值,可以尝试以下解决方法:
1. 首先,确保key的值在Redis中存在。可以通过使用Redis命令行工具或其他Redis客户端工具来验证key是否存在。
2. 如果key存在,但是对应的值为空,那么可能是因为在存储值的时候出现了问题。你可以检查存储值的代码,确保正确地将值存储到Redis中。
3. 另外,你还可以尝试使用其他方法来获取Redis中的值。例如,你可以使用redisTemplate.opsForHash()方法来获取哈希数据类型的值,或者使用redisTemplate.opsForList()方法来获取列表数据类型的值。这样可以验证是否是opsForValue()方法的问题。
4. 如果以上方法都没有解决问题,你可以尝试使用其他的Redis客户端来获取值,以确定是否是redisTemplate的问题。例如,你可以使用Jedis或Lettuce等第三方的Redis客户端来获取值。
总而言之,当redisTemplate.opsForValue().get(key)返回空值时,你可以通过验证key的存在性,检查存储值的代码,尝试使用其他方法获取Redis值,或者使用其他Redis客户端来确定问题的原因,并选择合适的解决方案[1]。
相关问题
根据 public R<Employee> findById(Integer id) { String key = "ab" + id; //查询缓存 String json = (String) redisTemplate.opsForValue().get(key); if (StrUtil.isNotBlank(json)) { Employee employee = JSONUtil.toBean(json, Employee.class); log.info("从缓存查询id为" + id); return R.success(employee); } //预防缓存穿透 //命中空值 if (json != null) { log.info("缓存命中空值,值不存在"); return R.error("缓存命中空值,值不存在"); } //添加锁 //防止缓存击穿 String lockKey = "s" + id; Employee employee = null; try { //尝试获取锁 boolean b = tryLock(lockKey); //没有获得锁,重试 if (!b) { return findById(id); } //缓存不存在,查询数据库 employee = getById(id); log.info("查询数据库id为" + id); if (employee == null) { //缓存空值解决 缓存穿透 redisTemplate.opsForValue().set(key, "", Duration.ofMinutes(2)); log.info("数据库查值为空"); return R.error("数据库查值为空"); } //添加缓存 redisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(employee), Duration.ofSeconds(60)); } catch (Exception e) { throw new RuntimeException(e); } finally { //释放锁 unlock(lockKey); } return R.success(employee); }用布隆过滤器修改
根据你提供的代码,可以在缓存查询之前添加布隆过滤器的判断,以防止缓存穿透。具体实现如下:
1. 引入布隆过滤器的依赖:
```
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.2-jre</version>
</dependency>
```
2. 在类中定义布隆过滤器和相关参数:
```
private BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), 10000, 0.01);
private final int BLOOM_FILTER_MAX_SIZE = 1000000;
```
其中,第一个参数是元素类型的 Funnel,第二个参数是布隆过滤器的最大容量,第三个参数是期望的误差率。
3. 在查询缓存之前,先判断该键是否可能存在于缓存中,如果不存在,则直接返回:
```
String key = "ab" + id;
if (!bloomFilter.mightContain(id)) {
log.info("布隆过滤器未命中,值不存在");
return R.error("布隆过滤器未命中,值不存在");
}
String json = (String) redisTemplate.opsForValue().get(key);
```
4. 在更新缓存时,将键值对添加到布隆过滤器中:
```
redisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(employee), Duration.ofSeconds(60));
bloomFilter.put(id);
```
这样,即使查询的键不存在于缓存中,也可以通过布隆过滤器的判断直接返回,而不会继续查询数据库,从而避免了缓存穿透的问题。
reactiveRedisTemplate.opsForValue().get() 判空转换
当你使用`reactiveRedisTemplate.opsForValue().get()`方法从 Redis 中获取值时,你需要判断返回值是否为 `null`。如果为 `null`,你可以使用 Java 8 的 `Optional` 类进行空值转换和过滤。以下是一个示例代码:
```
Optional<Mono<String>> optionalValue = Optional.ofNullable(reactiveRedisTemplate)
.map(template -> template.opsForValue().get("key"));
optionalValue.ifPresent(value -> {
value.subscribe(val -> {
// 在这里可以使用 val 进行操作
});
});
```
在上述代码中,首先使用`Optional.ofNullable()`方法将`reactiveRedisTemplate`对象转换为`Optional`对象。如果`reactiveRedisTemplate`对象为空,`Optional`对象将包含一个空值。如果`reactiveRedisTemplate`对象不为空,则使用`map()`方法将其转换为`Mono<String>`对象。最后,使用`ifPresent()`方法检查`Optional`对象是否包含非空值,如果包含则执行操作,这里是订阅 Mono 对象的值并在回调中进行操作。
需要注意的是,如果你使用了 `subscribe()` 方法来订阅 Mono 对象,那么在回调中进行操作时需要确保线程安全。因为 Mono 对象的操作是异步的,当 Mono 对象完成时,回调可能在不同的线程上执行。
阅读全文
相关推荐













