文章目录
- Spring Data Redis
- 一、Spring Data 介绍
- 二、Spring Data Redis
- 三、Spring Data Redis 入门
- 3.1 创建Spring Boot项目
- 3.2 项目配置
- 3.3 测试
- 四、序列化
- 4.1 RedisTemplate序列化分析
- 4.2 自定义RedisTemplate序列化
- 4.3 对象序列化
- 五、StringRedisTemplate
Spring Data Redis 一、Spring Data 介绍
Spring Data的任务是为数据访问提供一个熟悉且一致的、基于Spring的编程模型,同时保留底层数据存储的特殊特性。
它使数据访问技术、关系数据库和非关系数据库、map-reduce框架和基于云的数据服务的使用变得更加容易。这是一个伞形项目,其中包含许多特定于给定数据库的子项目。这些项目是通过与这些激动人心的技术背后的许多公司和开发人员合作开发的。
特征:
-
强大的存储库和自定义对象映射抽象
-
从存储库方法名称动态派生查
-
提供基本属性的实现域基类
-
支持透明审核(创建、上次更改)
-
集成自定义存储库代码的可能性
-
通过JavaConfig和自定义XML命名空间轻松集成Spring
-
与Spring MVC控制器的高级集成
-
对跨存储持久性的实验支持
返回顶部
二、Spring Data Redis
SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis,官网地址: https://spring.io/projects/spring-data-redis
- 提供了对不同Redis客户端的整合( Lettuce和Jedis)
- 提供了RedisTemplate统一API来操作Redis
- 支持Redis的发布订阅模型
- 支持Redis哨兵和Redis集群
- 支持基于Lettuce的响应式编程
- 支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化·支持基于Redis的JDKCollection实现
返回顶部
三、Spring Data Redis 入门
SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:
3.1 创建Spring Boot项目
选择需要的开发环境:Lombok、Spring Data Redis:
项目搭建完成:
返回顶部
3.2 项目配置
SpringBoot已经提供了对SpringDataRedis的支持,添加依赖配置:
org.springframework.boot spring-boot-starter-data-redis org.apache.commons commons-pool2
配置文件:
spring:
redis:
host: 192.168.64.178 # ip
port: 6379 # 端口
password: 123456 # 密码
lettuce: # 默认的客户端是lettuce,若要使用jedis需要添加依赖
pool:
max-active: 8 # 最大连接
max-idle: 8 # 最大空闲连接
min-idle: 0 # 最小空闲连接
max-wait: 100ms # 连接等待时间
database: 0 # 选择库
返回顶部
3.3 测试
package com.zyx;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
@SpringBootTest
class RedisDemoApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void testString() {
// 存储一条数据
redisTemplate.opsForValue().set("name", "Tom");
// 获取数据
Object name = redisTemplate.opsForValue().get("name");
System.out.println("name:" + name);
}
}
返回顶部
四、序列化 4.1 RedisTemplate序列化分析
通过上面的测试结果我们可以发现在存储的过程中出现了:xACxEDx00x05tx00x04name和xACxEDx00x05tx00x03Tom
不难发现,我们在使用客户端进行存储的时候,所有的api后的参数都是Object类型,这就涉及到了序列化的问题。
通过查看RedisTemplate源码可以发现常见的类型都实现了序列化:
并且采用的默认系列化器就是 JDK 的序列化方式:
这种方式会在写入前把Object序列化为字节的形式,然后进行存储,缺点很明显:可读性差、占用内存。所以我们需要修改默认的JDK序列化方式:
如上图所示,是主要的集中序列化方式。其中,key为字符串的时候我们通常使用StringRedisSerializer方式,value为字符串的时候,通常使用GenericJackson2JsonRedisSerializer方式。
返回顶部
4.2 自定义RedisTemplate序列化
在这之前需要配置Json序列化的依赖Jackson:
com.fasterxml.jackson.core jackson-databind
RedisConfig配置类:
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory){
// 创建RedisTemplate对象
RedisTemplate template = new RedisTemplate<>();
// 创建连接工厂
template.setConnectionFactory(connectionFactory);
// 创建Json序列化工具
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
// 设置key的序列化
template.setKeySerializer(RedisSerializer.string()); // return StringRedisSerializer.UTF_8;
template.setHashKeySerializer(RedisSerializer.string());
// 设置value的序列化
template.setValueSerializer(jsonRedisSerializer);
template.setHashKeySerializer(jsonRedisSerializer);
// 返回
return template;
}
}
测试:
@SpringBootTest
class RedisDemoApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
@Test
void testString() {
// 获取原始数据
Object nameBefore = redisTemplate.opsForValue().get("name");
System.out.println("nameBefore:" + nameBefore);
// 存储一条数据
redisTemplate.opsForValue().set("name", "Tom");
// 获取数据
Object nameAfter = redisTemplate.opsForValue().get("name");
System.out.println("nameAfter:" + nameAfter);
}
}
返回顶部
4.3 对象序列化
新建Student类,封装属性:name、age、sex:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
// 封装属性
private String name;
private char sex;
private int age;
}
测试类:
@Test
void testObject() {
// 存储一条数据
redisTemplate.opsForValue().set("student:1", new Student("张三",'男',20));
// 获取数据
Student s = (Student) redisTemplate.opsForValue().get("student:1");
System.out.println("s:" + s);
}
可以看到,针对于对象类型的数据确实按照配置的json形式进行了存贮,并且在获取数据的时候,将其转为了Student对象(因为在序列化的时候会添加一条@class的类路径属性,反序列化的时候就可以追踪到Student类上)。
但是与此同时会带来内存消耗的问题(类信息占有可能会多余有效信息)!
返回顶部
五、StringRedisTemplate
为了节省内存空间,我们一般实际中并不会使用JSON序列化器来处理value,而是统一使用String序列化器,要求只能存储String类型的key和value。当需要存储Java对象时,手动完成对象的序列化和反序列化。
也就是说全部使用String序列化器。当然Spring默认提供了一个StringRedisTemplate类,它的key和value的序列化方式默认就是String方式。省去了我们自定义RedisTemplate的过程:
private static final ObjectMapper mapper = new ObjectMapper();
@Test
void testObject() throws JsonProcessingException {
// 1.创建对象
Student s1 = new Student("李四", '男', 22);
// 2.手动序列化
String json = mapper.writeValueAsString(s1);
// 3.存储一条数据
stringRedisTemplate.opsForValue().set("student:2", json);
// 4.获取数据
String jsonStudent = stringRedisTemplate.opsForValue().get("student:2");
// 5.手动反序列化
Student s = mapper.readValue(jsonStudent, Student.class);
System.out.println("s:" + s);
}
返回顶部



