使用 RedisTemplate 从 Redis 获取 Set 值
Posted
技术标签:
【中文标题】使用 RedisTemplate 从 Redis 获取 Set 值【英文标题】:Get Set value from Redis using RedisTemplate 【发布时间】:2015-10-15 00:00:17 【问题描述】:我可以使用 Jedis
从 Redis
检索值:
public static void main(String[] args)
Jedis jedis = new Jedis(HOST, PORT);
jedis.connect();
Set<String> set = jedis.smembers(KEY);
for (String s : set)
System.out.println(s);
jedis.disconnect();
jedis.close();
但是当我尝试使用 Spring 的 RedisTemplate
时,我没有得到任何数据。我的数据以Set
的形式存储在Redis
。
// inject the actual template
@Autowired
private RedisTemplate<String, Object> template;
// inject the template as SetOperations
@Resource(name="redisTemplate")
private SetOperations<String,String> setOps;
public String logHome()
Set<String> set = setOps.members(KEY);
for(String str:set)
System.out.println(str); //EMPTY
Set<byte[]> keys = template.getConnectionFactory().getConnection().keys("*".getBytes());
Iterator<byte[]> it = keys.iterator();
while(it.hasNext())
byte[] data = (byte[])it.next();
System.out.println(new String(data, 0, data.length)); //KEYS are printed.
Set<Object> mySet = template.boundSetOps(KEY).members();
System.out.println(mySet); //EMPTY
return "";
有人可以指出我缺少什么吗?
编辑:我的 RedisTemplate xml 配置。
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
p:connection-factory-ref="jedisConnectionFactory"/>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="myhostname" p:port="6379" />
【问题讨论】:
【参考方案1】:总之
您必须配置序列化程序。
说明
Redis 模板对键、值和哈希键/值使用序列化程序。序列化器用于将 Java 输入转换为存储在 Redis 中的表示形式。如果您不配置任何内容,则序列化程序默认为JdkSerializationRedisSerializer
。因此,如果您在 Java 代码中请求密钥 key
,序列化程序会将其转换为
"\xac\xed\x00\x05t\x00\x03key"
Spring Data Redis 使用这些字节作为查询 Redis 的键。
您可以使用 Spring Data Redis 添加数据并使用 redis-cli
查询它:
template.boundSetOps("myKey").add(new Date());
然后在redis-cli
127.0.0.1:6379> keys *
1) "\xac\xed\x00\x05t\x00\x05myKey"
127.0.0.1:6379> SMEMBERS "\xac\xed\x00\x05t\x00\x05myKey"
1) "\xac\xed\x00\x05sr\x00\x0ejava.util.Datehj\x81\x01KYt\x19\x03\x00\x00xpw\b\x00\x00\x01N\xcf#\x9cHx"
如您所见,String 和 Date 被序列化为一些代表 Java 序列化对象的疯狂字节。
您的代码建议您要存储基于字符串的键和值。只需在您的RedisTemplate
中设置StringRedisSerializer
Java 配置
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
XML 配置
<bean id="stringSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"
p:connection-factory-ref="jedisConnectionFactory">
<property name="keySerializer" ref="stringSerializer"/>
<property name="valueSerializer" ref="stringSerializer"/>
</bean>
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:host-name="myhostname" p:port="6379"/>
运行代码后的输出如下所示:
value
key
[value]
Spring Data Redis 有一些有趣的序列化程序,允许在各种系统之间交换消息。您可以从内置的序列化程序中进行选择
JacksonJsonRedisSerializer Jackson2JsonRedisSerializer JdkSerializationRedisSerializer(默认) OxmSerializer GenericToStringSerializer或创建您自己的。
我使用 Spring Data Redis 1.5.1.RELEASE 和 jedis 2.6.2 来验证您的问题的结果。 HTH,马克
进一步阅读:
Spring Data Redis: Serializers Gist containing your example【讨论】:
我收到以下错误:在 ServletContext 资源 [/WEB-INF/root-context.xml] 中创建名称为“listener”的 bean 时出错:init 方法的调用失败;嵌套异常是 java.lang.IllegalArgumentException: RedisConnectionFactory is required 使用 java 配置工作正常。不知道为什么我收到 xml conf 错误。谢谢 我从 XML 示例中删除了 connectionFactory。我更新了代码,现在它正在工作。感谢您的提示。【参考方案2】:您可以使用Redisson 更轻松地做到这一点:
public static void main(String[] args)
Config conf = new Config();
conf.useSingleServer().setAddress(redisURL);
RedissonClient redisson = Redisson.create(conf);
RSet<String> set = redisson.getSet("key")
for (String s : set.readAllValues())
System.out.println(s);
redisson.shutdown();
这个框架处理序列化和连接,所以你不需要每次都处理它。像使用 Java 对象(Set、Map、List ...)一样使用 Redis。它也支持许多流行的编解码器。
【讨论】:
以上是关于使用 RedisTemplate 从 Redis 获取 Set 值的主要内容,如果未能解决你的问题,请参考以下文章
springboot整合redis——redisTemplate的使用
Redis 数据类型操作指令以及对应的RedisTemplate方法