通过`RedisTemplate`使用对象
大多数用户可能会使用RedisTemplate
及其对应的包`org.springframework.data.redis.core`,或者其响应式变体ReactiveRedisTemplate
。实际上,由于其丰富的功能集,模板是Redis模块的核心类。模板为Redis交互提供了高级抽象。虽然`[Reactive]RedisConnection`提供接受和返回二进制值(`byte`数组)的低级方法,但模板负责序列化和连接管理,从而使用户无需处理这些细节。
引用`[Reactive]RedisTemplate`实例操作的首选方法是通过`[Reactive]RedisOperations`接口。 |
此外,模板提供操作视图(遵循Redis命令参考中的分组),这些视图为针对特定类型或特定键(通过`KeyBound`接口)的工作提供了丰富的泛型接口,如下表所述
操作视图
-
命令式
-
响应式
接口 | 描述 |
---|---|
键类型操作 |
|
Redis地理空间操作,例如`GEOADD`、`GEORADIUS`…… |
|
Redis哈希操作 |
|
Redis HyperLogLog操作,例如`PFADD`、`PFCOUNT`…… |
|
Redis列表操作 |
|
Redis集合操作 |
|
Redis字符串(或值)操作 |
|
Redis zset(或有序集合)操作 |
|
键绑定操作 |
|
Redis键绑定地理空间操作 |
|
Redis哈希键绑定操作 |
|
Redis键绑定操作 |
|
Redis列表键绑定操作 |
|
Redis集合键绑定操作 |
|
Redis字符串(或值)键绑定操作 |
|
Redis zset(或有序集合)键绑定操作 |
接口 | 描述 |
---|---|
键类型操作 |
|
Redis地理空间操作(例如`GEOADD`、`GEORADIUS`等) |
|
Redis哈希操作 |
|
Redis HyperLogLog操作(例如`PFADD`、`PFCOUNT`等) |
|
Redis列表操作 |
|
Redis集合操作 |
|
Redis字符串(或值)操作 |
|
Redis zset(或有序集合)操作 |
配置完成后,模板是线程安全的,可以在多个实例中重用。
RedisTemplate
在其大多数操作中使用基于Java的序列化器。这意味着模板写入或读取的任何对象都通过Java进行序列化和反序列化。
您可以更改模板上的序列化机制,Redis模块提供了几个实现,这些实现位于`org.springframework.data.redis.serializer`包中。有关更多信息,请参见序列化器。您也可以将任何序列化器设置为null,并通过将`enableDefaultSerializer`属性设置为`false`来使用原始字节数组使用RedisTemplate。请注意,模板要求所有键都不为null。但是,只要底层序列化器接受,值可以为null。阅读每个序列化器的Javadoc以获取更多信息。
对于需要特定模板视图的情况,请将视图声明为依赖项并注入模板。容器会自动执行转换,从而消除`opsFor[X]`调用,如下例所示
-
Java命令式
-
Java响应式
-
XML
@Configuration
class MyConfig {
@Bean
LettuceConnectionFactory connectionFactory() {
return new LettuceConnectionFactory();
}
@Bean
RedisTemplate<String, String> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, String> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
return template;
}
}
@Configuration
class MyConfig {
@Bean
LettuceConnectionFactory connectionFactory() {
return new LettuceConnectionFactory();
}
@Bean
ReactiveRedisTemplate<String, String> ReactiveRedisTemplate(ReactoveRedisConnectionFactory connectionFactory) {
return new ReactiveRedisTemplate<>(connectionFactory, RedisSerializationContext.string());
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"/>
<!-- redis template definition -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="redisConnectionFactory"/>
...
</beans>
-
命令式
-
响应式
public class Example {
// inject the actual operations
@Autowired
private RedisOperations<String, String> operations;
// inject the template as ListOperations
@Resource(name="redisTemplate")
private ListOperations<String, String> listOps;
public void addLink(String userId, URL url) {
listOps.leftPush(userId, url.toExternalForm());
}
}
public class Example {
// inject the actual template
@Autowired
private ReactiveRedisOperations<String, String> operations;
public Mono<Long> addLink(String userId, URL url) {
return operations.opsForList().leftPush(userId, url.toExternalForm());
}
}
以字符串为中心的便捷类
由于Redis中存储的键和值通常是`java.lang.String`,因此Redis模块分别为`RedisConnection`和`RedisTemplate`提供了两个扩展,分别是`StringRedisConnection`(及其`DefaultStringRedisConnection`实现)和`StringRedisTemplate`,作为密集字符串操作的便捷一站式解决方案。除了绑定到`String`键外,模板和连接还在底层使用`StringRedisSerializer`,这意味着存储的键和值是人类可读的(假设Redis和您的代码都使用相同的编码)。以下列表显示了一个示例
-
Java命令式
-
Java响应式
-
XML
@Configuration
class RedisConfiguration {
@Bean
LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory();
}
@Bean
StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
@Configuration
class RedisConfiguration {
@Bean
LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory();
}
@Bean
ReactiveStringRedisTemplate reactiveRedisTemplate(ReactiveRedisConnectionFactory factory) {
return new ReactiveStringRedisTemplate<>(factory);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"/>
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connection-factory-ref="redisConnectionFactory"/>
</beans>
-
命令式
-
响应式
public class Example {
@Autowired
private StringRedisTemplate redisTemplate;
public void addLink(String userId, URL url) {
redisTemplate.opsForList().leftPush(userId, url.toExternalForm());
}
}
public class Example {
@Autowired
private ReactiveStringRedisTemplate redisTemplate;
public Mono<Long> addLink(String userId, URL url) {
return redisTemplate.opsForList().leftPush(userId, url.toExternalForm());
}
}
与其他Spring模板一样,RedisTemplate
和 StringRedisTemplate
允许您通过RedisCallback
接口直接与Redis进行交互。此功能为您提供了完全的控制权,因为它直接与RedisConnection
进行通信。请注意,当使用StringRedisTemplate
时,回调会接收StringRedisConnection
的实例。以下示例演示了如何使用RedisCallback
接口。
public void useCallback() {
redisOperations.execute(new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection) throws DataAccessException {
Long size = connection.dbSize();
// Can cast to StringRedisConnection if using a StringRedisTemplate
((StringRedisConnection)connection).set("key", "value");
}
});
}
序列化器
从框架的角度来看,存储在Redis中的数据只是字节。虽然Redis本身支持各种类型,但在大多数情况下,这些类型指的是数据的存储方式而不是其表示的内容。用户需要决定信息是否转换为字符串或任何其他对象。
在Spring Data中,用户(自定义)类型和原始数据之间的转换(反之亦然)由Spring Data Redis中的org.springframework.data.redis.serializer
包处理。
此包包含两种类型的序列化器,顾名思义,它们负责序列化过程。
-
基于
RedisSerializer
的双向序列化器。 -
使用
RedisElementReader
和RedisElementWriter
的元素读取器和写入器。
这些变体之间的主要区别在于RedisSerializer
主要序列化为byte[]
,而读取器和写入器使用ByteBuffer
。
有多种实现可用(包括本文档中已提到的两种)。
-
JdkSerializationRedisSerializer
,它默认用于RedisCache
和RedisTemplate
。 -
StringRedisSerializer
。
但是,可以使用OxmSerializer
通过Spring OXM支持进行对象/XML映射,或者使用Jackson2JsonRedisSerializer
或GenericJackson2JsonRedisSerializer
以JSON格式存储数据。
请注意,存储格式不仅限于值。它可以无限制地用于键、值或哈希。
默认情况下, 如果您担心Java序列化造成的安全漏洞,请考虑核心JVM级别的通用序列化过滤器机制。 |