SpringDataRedis的入门案例,以及RedisTemplate序列化实现
目录
SpringDataRedis
简单介绍
入门案例
RedisTemplate序列化方案
方案一:
方案二:
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: localhostport: 6379database: 0password: root@123456lettuce:pool:max-active: 8max-idle: 8min-idle: 0max-wait: -1ms
3.注入RedisTemplate,简单测试
@SpringBootTest
class RedisDemoApplicationTests {@Autowiredprivate RedisTemplate redisTemplate;
@Testvoid 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 {@Beanpublic 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 {
@Autowiredprivate RedisTemplate<String, Object> redisTemplate;
@Testvoid testString() {redisTemplate.opsForValue().set("name", "John");String name = (String) redisTemplate.opsForValue().get("name");System.out.println(name);}
@Testvoid 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 {
@Autowiredprivate StringRedisTemplate StringRedisTemplate;
@Testvoid testString() {StringRedisTemplate.opsForValue().set("name", "John");String name = StringRedisTemplate.opsForValue().get("name");System.out.println(name);}
private static final ObjectMapper mapper = new ObjectMapper();
@Testvoid testSaveUser() throws JsonProcessingException {写入数据User user = new User("John", 25);System.out.println(user);//手动序列化String json = mapper.writeValueAsString(user);//写入redisStringRedisTemplate.opsForValue().set("user", json);
//读取数据User savedUser = mapper.readValue(json, User.class);System.out.println(savedUser);}
}
5.Redis图形化界面