目录
SpringDataRedis
简单介绍
-
提供了对不同Redis客户端的整合(Lettuce和Jedis)
-
提供了RedisTemplate统一API来操作Redis
-
支持Redis的发布订阅模型
-
支持Redis哨兵和Redis集群
-
支持基于Lettuce的响应式编程
-
支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化
-
支持基于Redis的JDKCollection实现
入门案例
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>
</dependency>
2.配置Redis
spring:
data:
redis:
host: localhost
port: 6379
database: 0
password: root@123456
lettuce:
pool:
max-active: 8
max-idle: 8
min-idle: 0
max-wait: -1ms
3.注入RedisTemplate,简单测试
@SpringBootTest
class RedisDemoApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void testString() {
redisTemplate.opsForValue().set("name", "John");
String name = (String) redisTemplate.opsForValue().get("name");
System.out.println(name);
}
}
是不是感觉挺简单的?但这样会出现一个问题,那就是存入的数据,默认是采用jdk的序列化和反序列化,也就导致存入redis中的数据,是一个长串,可读性较差。
如下图:
并且还面临一个问题,大家在redis图形界面的命令行操作name时,会发现,数据并没有改变。
这是因为Java一直在对序列化的key(也就是长串)对应的值进行操作,那么怎么解决这个问题呢?
这就需要提到RedisTemplate序列化方案,具体怎么实现呢,下面是两种方案的具体实现。
RedisTemplate序列化方案
方案一:
-
自定义RedisTemplate
-
修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer
@Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { //创建RedisTemplate对象 RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); //设置连接工厂 redisTemplate.setConnectionFactory(redisConnectionFactory); //创建JSON序列化工具 GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(); //设置Key的序列化 redisTemplate.setKeySerializer(serializer); redisTemplate.setHashKeySerializer(serializer); //设置Value的序列化 redisTemplate.setValueSerializer(serializer); redisTemplate.setHashValueSerializer(serializer); return redisTemplate; } }
3.测试类:
@SpringBootTest
class DemoApplicationTests {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Test
void testString() {
redisTemplate.opsForValue().set("name", "John");
String name = (String) redisTemplate.opsForValue().get("name");
System.out.println(name);
}
@Test
void testSaveUser() {
//写入数据
User user = new User("John", 25);
System.out.println(user);
redisTemplate.opsForValue().set("user", user);
User savedUser = (User) redisTemplate.opsForValue().get("user");
System.out.println(savedUser);
}
}
4.Redis图形界面如下:(有冗余字段,比如@class)
而实际上,这样存储虽然对于机器来说更便于读取,但占用的空间是很大的。尤其是对于redis来说,内存的存储空间还是比较珍贵的,这么浪费是不太好的。
事实上,咱们程序员在封装写入redis,或者读取时是知道数据类型的,那么自行对字段进行序列化即可解决该问题,请看下述方案二。
方案二:
1.使用StringRedisTemplate(写入或读取都直接收字符串)
2.写入Redis时,手动把对象序列化为JSON串
3.读取Redis时,手动把读取到的JSON反序列化为对象
4.简易测试类:
@SpringBootTest
class RedisStringTests {
@Autowired
private StringRedisTemplate StringRedisTemplate;
@Test
void testString() {
StringRedisTemplate.opsForValue().set("name", "John");
String name = StringRedisTemplate.opsForValue().get("name");
System.out.println(name);
}
private static final ObjectMapper mapper = new ObjectMapper();
@Test
void testSaveUser() throws JsonProcessingException {
写入数据
User user = new User("John", 25);
System.out.println(user);
//手动序列化
String json = mapper.writeValueAsString(user);
//写入redis
StringRedisTemplate.opsForValue().set("user", json);
//读取数据
User savedUser = mapper.readValue(json, User.class);
System.out.println(savedUser);
}
}
5.Redis图形化界面