一、RedisTemplate介绍
1、简介
RedisTemplate 是 Spring Data Redis 提供的一个高级抽象,由 Spring 官方提供的方便操作 Redis 数据库的一个工具类,支持模板设计模式,使得操作 Redis 更加符合 Spring 的编程模型。还支持序列化机制,可以处理 Java 对象的存取。其本质属于 Spring-Data 模块下的 Spring-Data-Redis 部分,它提供了从 Spring 应用程序轻松配置和访问 Redis的功能。
2、原理
Spring-Data-Redis 是通过整合Lettuce和Jedis这俩种Redis客户端产生的,对外则提供了RedisTemplate这样统一的API来供调用者访问。它既支持Luttuce的响应式编程也支持JDK中集合的实现。
3、和Jedis的区别
Jedis 是一个用于直接与 Redis 服务器通信的 Java 客户端库,它提供了 Redis 所有基本功能的直接 API,需要手动管理连接(如创建 Jedis
实例和处理连接关闭等),并且需要在项目中引入 Jedis 的相关 Maven 依赖,Jedis 适合需要精细控制 Redis 操作的场景,直接提供 Redis 命令的操作方式;
RedisTemplate 更加适合与 Spring 框架集成的应用,提供了更高层次的抽象和便利的方法来简化 Redis 操作。
具体选用客户端还是模板,根据项目实际需要即可。
二、RedisTemplate使用
1、引入依赖
<!--Redis依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--连接池依赖-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.11.1</version>
</dependency>
2、配置连接
由于 RedisTemplate 是整合的Lettuce和Jedis,因此在配置连接池的时候需要进行选择是使用Lettuce还是Jedis(默认是Lettuce)
#Redis cache setting
spring.data.redis.host=127.0.0.1
spring.data.redis.port=6379
spring.data.redis.password=
#最大连接数
spring.data.redis.lettuce.pool.max-active=8
#等待时长
spring.data.redis.lettuce.pool.max-wait=-1
#最大空闲连接
spring.data.redis.lettuce.pool.max-idle=8
#最小空闲连接
spring.data.redis.lettuce.pool.min-idle=0
spring.data.redis.lettuce.pool.enabled=true
spring.data.redis.lettuce.pool.time-between-eviction-runs=30s
3、使用
通过依赖注入就可以直接使用
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testString(){
String key = "name";
//存
String value = "这是value123";
redisTemplate.opsForValue().set(key,value);
//取
Object valueObj = redisTemplate.opsForValue().get(key);
System.out.println("value为:" + valueObj);
}
执行打印:value为:这是value123
4、序列化
注意点:上面存入的数据打开Redis图形化工具查看发现是一堆乱码
这是因为Redis的序列化并没有按照我们预期的进行转化,我们需要自己去重写一个序列化,如下将key设置为String类型、value设置为json类型,最后将这个对象交给Spring管理,之后在调用该对象的时候就会自动选择我们配置的这个:
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
//创建RedisTemplate对象
RedisTemplate<String, Object> template = new RedisTemplate<>();
//设置连接工厂
template.setConnectionFactory(connectionFactory);
//创建JSON序列化工具
GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer();
//设置key的序列化
template.setKeySerializer(RedisSerializer.string());
template.setHashValueSerializer(RedisSerializer.string());
//设置value的序列化
template.setValueSerializer(jsonSerializer);
template.setHashValueSerializer(jsonSerializer);
return template;
}
}
对于JSON序列化工具也需要引入依赖:
<!--jackson依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.1</version>
</dependency>
此时存储正常:
redis的序列化方式有:
@Configuration
@EnableConfigurationProperties(RedisProperties.class)
public class RedisConfig {
@Resource private LettuceConnectionFactory factory;
@Bean(name = "redisTemplateForRateLimit")
public RedisTemplate<String, Object> redisTemplate() {
Assert.notNull(factory, "can not initialise [RedisConnectionFactory]");
Jackson2JsonRedisSerializer<Object> jacksonSerializer =
new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = getObjectMapper();
jacksonSerializer.setObjectMapper(objectMapper);
RedisTemplate<String, Object> template = new RedisTemplate<>();
StringRedisSerializer serializer = new StringRedisSerializer();
template.setKeySerializer(serializer);
template.setHashKeySerializer(serializer);
template.setValueSerializer(jacksonSerializer);
template.setHashValueSerializer(jacksonSerializer);
template.setDefaultSerializer(jacksonSerializer);
template.setConnectionFactory(factory);
template.afterPropertiesSet();
return template;
}
}
三、StringRedisTemplate
1、简介
由于存储在 Redis 中的 key 和 value 通常是很常见的 String 类型,Redis模块提供了 RedisConnection 和 RedisTemplate 的扩展,分是 StringRedisConnection 和 StringRedisTemplate,作为字符串操作的解决方案。
通过源码可以看见对于Key、Value、HashKey、HashValue都是进行String类型的序列化。
因此对于一些复杂类型,如对象在StringRedisTemplate的时候往往需要自己手动序列化将对象转为JSON再存入Redis。
2、集成
同上,不过使用StringRedisTemplate操作的都是string,所以不需要(写RedisConfig)额外设置序列化,因此存取对象需要自己序列化、反序列化。
3、使用demo
操作string:
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
public void testString(){
String key = "string-name";
//存
String value = "这是value123";
stringRedisTemplate.opsForValue().set(key,value);
//取
Object valueObj = stringRedisTemplate.opsForValue().get(key);
System.out.println("value为:" + valueObj);
}
输出:value为:这是value123,
查看可视化工具也没有乱码
操作对象:
import com.alibaba.fastjson.JSON;
import org.example.Main;
import org.example.dto.UserDTO;
import org.example.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
public void testUser(){
String key = "user-key";
//存
UserDTO userDTO = new UserDTO();
userDTO.setUserAccount("zhangsan");
userDTO.setAge(18);
userDTO.setUserName("张三");
stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(userDTO));
//取
String valueObj = stringRedisTemplate.opsForValue().get(key);
UserDTO redisUser = JSON.parseObject(valueObj, UserDTO.class);
System.out.println("value为:" + redisUser);
}
输出:value为:UserDTO(userName=张三, age=18, userAccount=zhangsan)
查看可视化工具没有乱码: