解决使用redisTemplate set方法保存出现\x00\问题

解决使用redisTemplate set方法保存出现\x00\问题

(这是一个细节问题,很容易被坑: 引用博客 https://www.cnblogs.com/linyb-geek/archive/2020/06/17/13153775.html?ivk_sa=1024320u)

在项目有个需求要保存一个字符串到redis,并设置一个过期时间。这个需求一看非常简单,使用redisTemplate一行代码搞定,代码如下

redisTemplate.opsForValue().set(“userKey”, data, 10000);
但保存后,查看redis发现value的前缀多出了

\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x
一开始以为是redis的序列化问题,于是就修改了redisTemplate的序列化方式,终于还是没能解决问题。那问题出在哪里?翻看源码,发现redisTemplate.opsForValue().set()有重载方法,一个是

void set(K key, V value, long offset)
另外一个是

void set(K key, V value, long timeout, TimeUnit unit)
调用set(K key, V value, long offset)这个方法,其底层调用的是redis的setrange命令,这个命令看官网介绍

Overwrites part of the string stored at key, starting at the specified offset, for the entire length of value. If the offset is larger than the current length of the string at key, the string is padded with zero-bytes to make offset fit. Non-existing keys are considered as empty strings, so this command will make sure it holds a string large enough to be able to set value at offset

其含义是从指定的偏移量开始,覆盖整个值范围内从key存储的字符串的一部分。如果偏移量大于key处字符串的当前长度,则该字符串将填充零字节以使偏移量适合。不存在的键被视为空字符串,因此此命令将确保它包含足够大的字符串以能够将值设置为offset。

调用set(K key, V value, long timeout, TimeUnit unit)这个方法,其底层调用的是redis命令setex。这个命令看官网介绍

Set key to hold the string value and set key to timeout after a given number of seconds

很显然这个方法,才是我们真正想要的方法。因此解决使用restemplate set方法保存出现\x00\问题的方案就是使用

void set(K key, V value, long timeout, TimeUnit unit)
这个方法

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用RedisTemplate实现set去重,你可以使用RedisSet数据结构以及RedisTemplate中提供的相关方法。下面是一个简单示例代码: ```java import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.SetOperations; // 在使用之前,请确保已经正确配置了RedisTemplate public class SetDeduplicationExample { private RedisTemplate<String, String> redisTemplate; public SetDeduplicationExample(RedisTemplate<String, String> redisTemplate) { this.redisTemplate = redisTemplate; } public void deduplicateSet(String key, String... values) { SetOperations<String, String> setOperations = redisTemplate.opsForSet(); // 将元素添加到Set中,返回添加成功的元素个数 Long addedCount = setOperations.add(key, values); // 获取Set中的所有元素 Set<String> allElements = setOperations.members(key); // 如果添加成功的元素个数等于values数组的长度,表示所有元素都是新的,无需去重 if (addedCount != null && addedCount == values.length) { System.out.println("All elements are new, no deduplication needed."); return; } // 如果Set中的元素个数等于values数组的长度,表示所有元素都已存在,无需去重 if (allElements != null && allElements.size() == values.length) { System.out.println("All elements already exist, no deduplication needed."); return; } // 从Set中移除已存在的元素 setOperations.remove(key, values); // 将剩余的新元素重新添加到SetsetOperations.add(key, values); System.out.println("Deduplication completed."); } } ``` 在上面的示例中,`deduplicateSet`方法接收一个键(key)和一个或多个值(values)作为参数,它会将所有的值添加到RedisSet中,并进行去重操作。如果所有的值都是新的,或者所有的值都已存在于Set中,则不执行去重操作。否则,它会从Set中移除已存在的元素,并重新添加剩余的新元素。 注意:这只是一个简单的示例,实际使用时需要根据具体的业务需求进行适当的调整和错误处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值