Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当绝地武士使用Spring数据时,为什么数据会被存储在Redis中?_Redis_Spring Data_Jedis - Fatal编程技术网

当绝地武士使用Spring数据时,为什么数据会被存储在Redis中?

当绝地武士使用Spring数据时,为什么数据会被存储在Redis中?,redis,spring-data,jedis,Redis,Spring Data,Jedis,我在绝地使用Spring数据Redis。我正在尝试使用键vc:${list\u id}存储哈希。我能够成功地插入到redis。但是,当我使用redis cli检查密钥时,我没有看到密钥vc:501381。相反,我看到的是\xac\xed\x00\x05t\x00\tvc:501381 为什么会发生这种情况?我如何改变这种情况 好的,在谷歌上搜索了一会儿,在上找到了帮助 这是因为Java序列化 redisTemplate的密钥序列化程序需要配置为StringRedisSerializer,即如下所

我在绝地使用Spring数据Redis。我正在尝试使用键
vc:${list\u id}
存储哈希。我能够成功地插入到redis。但是,当我使用redis cli检查密钥时,我没有看到密钥
vc:501381
。相反,我看到的是
\xac\xed\x00\x05t\x00\tvc:501381


为什么会发生这种情况?我如何改变这种情况

好的,在谷歌上搜索了一会儿,在上找到了帮助

这是因为Java序列化

redisTemplate的密钥序列化程序需要配置为
StringRedisSerializer
,即如下所示:


现在redis中的键是
vc:501381

或者像@niconic所说的,我们也可以将默认序列化程序本身设置为字符串序列化程序,如下所示:


这意味着我们所有的键和值都是字符串。但是请注意,这可能不是最好的,因为您可能希望您的值不仅仅是字符串

如果您的值是一个域对象,那么您可以使用Jackson serializer并按照所述配置一个序列化程序,例如:


并将模板配置为:


您必须序列化要发送给redis的对象。下面是它的完整运行示例。它使用接口
DomainObject
作为
Serializable

以下是步骤

1) 使用以下jar创建maven pom.xml


org.springframework


示例代码取自使用StringRedisTemplate替换RedisTemplate

默认情况下,
redisplate
使用Java序列化,
stringredisplate
使用
stringredisalizer


我知道这个问题已经有一段时间了,但最近我又对这个主题做了一些研究,所以我想在这里分享一下如何通过查看部分spring源代码来生成这个“半哈希”键

首先,Spring利用AOP解析注释,如
@Cacheable、@cacheexecute或@CachePut
等。advice类是来自Spring上下文依赖项的
CacheInterceptor
,它是
CacheAspectSupport
的子类(也来自Spring上下文)。为了便于解释,我将使用
@Cacheable
作为示例,在这里浏览部分源代码

调用注释为
@Cacheable
的方法时,AOP会将其路由到此方法
protectedcollection serializer=redisOperations.getValueSerializer()!=无效的redisOperations.getValueSerializer()文件
:(重新序列化程序)新的JdkSerializationRedisSerializer();
this.cacheMetadata=新的RedisCacheMetadata(名称、前缀);
this.cacheMetadata.setDefaultExpiration(到期);
this.redisOperations=redisOperations;
this.cacheValueAccessor=新的cacheValueAccessor(序列化程序);
如果(allowNullValues){
如果(redisOperations.getValueSerializer()实例为StringRedisSerializer
||redisOperations.getValueSerializer()实例为GenericToStringSerializer
||redisOperations.getValueSerializer()实例JacksonJSONRedisializer
||redisOperations.getValueSerializer()实例(Jackson2JSONRedisializer){
抛出新的IllegalArgumentException(String.format(
“Redis不允许具有空值的键”\\_(ツ)_/¯. "
+“所选%s不支持泛型类型处理,因此无法在启用allowNullValues的情况下使用。”
+“请使用其他重新序列化程序或禁用空值支持。”,
getShortName(redisOperations.getValueSerializer().getClass());
}
}
}
那么
prefix
在这个RedisCache中的用法是什么呢?-->如构造函数中所示,它在这个语句中使用
this.cacheMetadata=new RedisCacheMetadata(name,prefix);
,下面的
RedisCacheMetadata
的构造函数显示了更多细节:

/**
*@param cacheName不能为{@literal null}或空。
*@param keyPrefix可以是{@literal null}。
*/
公共RedisCacheMatadata(字符串cacheName,字节[]键前缀){
Assert.hasText(cacheName,“cacheName不能为null或空!”);
this.cacheName=cacheName;
this.keyPrefix=keyPrefix;
StringRedisSerializer stringSerializer=新的StringRedisSerializer();
//持有密钥的集合的名称
this.setOfKnownKeys=usesKeyPrefix()?新字节[]{}:stringSerializer.serialize(cacheName+“~keys”);
this.cacheLockName=stringSerializer.serialize(cacheName+“~lock”);
}
此时,我们知道一些prefix参数已设置为
RedisCacheMetadata
,但该前缀如何用于在Redis中形成键(例如,您提到的\xac\xed\x00\x05t\x00\tvc:501381)

基本上,
CacheInterceptor
随后将向前调用方法
private RedisCacheKey getRedisCacheKey(对象键)
来自上述
RedisCache
对象,该对象使用
RedisCacheMetadata
中的前缀和
RedisOperation
中的键序列化器返回
RedisCacheKey
的实例

私有RedisCacheKey getRedisCacheKey(对象密钥){
返回新的RedisCacheKey(key).usePrefix(this.cacheMetadata.getKeyPrefix())
.withKeySerializer(redisOperations.getKeySerializer());
}
到达这一点后,
CacheInterceptor
的“pre”建议完成,它将继续执行由
@Cacheable
注释的实际方法。在完成实际方法的执行后,它将执行