首页 > 数据库 >SpringDataRedis的序列化方式和StringRedisTemplate手动序列化详解

SpringDataRedis的序列化方式和StringRedisTemplate手动序列化详解

时间:2023-04-21 21:33:10浏览次数:41  
标签:SpringDataRedis name User template 序列化 StringRedisTemplate RedisTemplate user

一.SpringDataRedis

之前新创建一个Spring项目,在进行配置完成redis和common-pool依赖:

1.引入依赖redis:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

2.引入common-pool依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

我们去yaml里配置redis链接配置:

spring:
  data:
    redis:
      database: 0
      port: 6379
      host: 127.0.0.1
      jedis:
        pool:
          min-idle: 0
          max-idle: 8
          max-active: 8
          max-wait: 100ms

配置设定他的库位置,端口号,ip地址,最大连接数,保活数,和最大延时等待时间。

去单元测试里:

@Autowired
private RedisTemplate redisTemplate;

@Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Autowired的使用来消除 set ,get方法。

配置单元测试,我们存储一个键值对:

@Test
void testString() {
    redisTemplate.opsForValue().set("name","xiaozhu");
    Object name = redisTemplate.opsForValue().get("name");
    System.out.println("name"+name);
}

运行结果:

image-20230309090757184

RESP效果如下:

image-20230309090734434

1.1 SpringDataRedis总结

SpringDataRedis 的使用步骤:

1. 引入 spring-boot-starter-data-redis 依赖

2.在 application.yml 配置 Redis 信息

3.注入 RedisTemplate

1.2 SpringDataRedis的序列化方式

Red is Template 可以接收任意 Object 作为值写入 Red is, 只不过写入前会把 Object 序列化为字节形式, 默认是采用 JDK 序列化,得到的结果是这样的:

image-20230309092102028

缺点:

  • 可读性差
  • 内存占用较大
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory){
    RedisTemplate<String,Object> template = new RedisTemplate<>();
    template.setConnectionFactory(connectionFactory);
    GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
    template.setKeySerializer(RedisSerializer.string());
    template.setHashKeySerializer(RedisSerializer.string());
    template.setValueSerializer(jsonRedisSerializer);
    template.setHashValueSerializer(jsonRedisSerializer);
    return template;
}

创建RedisTemplate对象

RedisTemplate<String,Object> template = new RedisTemplate<>();

设置链接工厂

template.setConnectionFactory(connectionFactory);

创建JSON序列化工具

GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();

设置Key序列化:

template.setKeySerializer(RedisSerializer.string());
template.setHashKeySerializer(RedisSerializer.string());

设置Value的序列化:

template.setValueSerializer(jsonRedisSerializer);
template.setHashValueSerializer(jsonRedisSerializer);

返回

return template;

引入Jackson依赖

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.14.2</version>
</dependency>

运行单元测试:运行成功

image-20230309195159199

1.3User案例(序列化与反序列化)

新建User对象。

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private String name;
    private Integer age;
}

写一个test测试集:

@Test
void testSaveUser(){
    redisTemplate.opsForValue().set("user:100",new User("上进小菜猪",21));
    User o=(User) redisTemplate.opsForValue().get("user:100");
}

运行结果:

image-20230310084911970

RESP截图:Json格式。

image-20230310084944612

输出运行结果,检测反序列化:

System.out.println("o="+o);

image-20230310085136724

二.StringRedisTemplate

尽管 JSON 的序列化方式可以满足我们的需求,但依然存在一些问题,如图:

image-20230310085418028

为了在反序列化时知道对象的类型,JSON 序列化器会将类的 class 类型写入 json 结果中,存入 Redis,会带来额外的内存开销。

为了节省内存空间,我们并不会使用 JSON 序列化器来处理 value,而是统一使用 String 序列化器,要求只能存储 String 类型的 key 和 value。当需要存储 Java 对象时,手动完成对象的序列化和反序列化。

思路如下:

image-20230310085621891

2.1 StringRedisTemplate 类

Spring 默认提供了一个 StringRedisTemplate 类,它的 key 和 value 的序列化方式默认就是 String 方式。省去了我们自义 RedisTemplate 的过程:

新建测试类:

RedisStringTests

建立:StringRedisTemplate对象

@Autowired
private StringRedisTemplate stringRedisTemplate;

测试类

@Test
void testString() {
    stringRedisTemplate.opsForValue().set("name","小猪");
    Object name = stringRedisTemplate.opsForValue().get("name");
    System.out.println("name"+name);
}

运行结果:

image-20230310090544763

单元测试集:

@Test
void testSaveUser() throws JsonProcessingException {
    User user = new User("小菜猪",21);

    String json = mapper.writeValueAsString(user);

    stringRedisTemplate.opsForValue().set("user:200",json);

    String jsonUser=stringRedisTemplate.opsForValue().get("user:200");

    User user1 = mapper.readValue(jsonUser, User.class);

    System.out.println("user"+user1);
    
}

代码解释: 创建对象:

User user = new User("小菜猪",21);

手动序列化:

String json = mapper.writeValueAsString(user);

写入数据:

stringRedisTemplate.opsForValue().set("user:200",json);

取出数据:

String jsonUser=stringRedisTemplate.opsForValue().get("user:200");

手动反序列化:

User user1 = mapper.readValue(jsonUser, User.class);

运行结果如下: image-20230310091613974

image-20230310091619516

哈希举例:

    @Test
    void testHash(){
        stringRedisTemplate.opsForHash().put("user:400","name","上进小菜猪");
        stringRedisTemplate.opsForHash().put("user:400","age","21");

//        Map<Object,Object> enteies=stringRedisTemplate.opsForValue().entries();
        Map<Object,Object> enteies= stringRedisTemplate.opsForHash().entries("user:400");

        System.out.println("entries"+enteies);
    }

运行结果如下:

image-20230310092527476

2.2 总结

RedisTemplate 的两种序列化实践方案:

方案一: l.自定义 RedisTemplate 2.修改 RedisTemplate 的序列化器为 GenericJackson2 JsonRedisSerializer

方案二: 1.使用 StringRedisTemplate 2.写入 Redisl 时,手动把对象序列化为 JSON 3.读取 Redis 时,手动把读取到的 JSON 反序列化为对象

标签:SpringDataRedis,name,User,template,序列化,StringRedisTemplate,RedisTemplate,user
From: https://blog.51cto.com/u_15568258/6211777

相关文章

  • drf之多表关联反序列化保存read_only与write_only
    目录read_only与write_only示例假如前端传入了一组数据:{name:'赛尔达传说:王国之泪',price:350,publish:1,authors:[1,2]}如上:publish按id传入,authors也按id传入。read_only与write_onlyread_only用于序列化write_only用于反序列化这两个是字段参数示例#......
  • java -- 缓冲流、转换流、序列化流
    缓冲流缓冲流,也叫高效流,按照数据类型分类:字节缓冲流:BufferedInputStream,BufferedOutputStream字符缓冲流:BufferedReader,BufferedWriter缓冲流的基本原理,是在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而提高读写的效率。字节缓......
  • javasec(四)序列化与反序列化基本原理
    title:javasec(四)序列化与反序列化基本原理tags:-javasec-反序列化categories:-javaseccover:'https://blog-1313934826.cos.ap-chengdu.myqcloud.com/blog-images/1.jpeg'feature:falsedate:2023-04-1816:02:20这篇文章介绍java序列化与反序列化基本原......
  • javasec(五)URLDNS反序列化分析
    这篇文章介绍URLDNS就是ysoserial中⼀个利⽤链的名字,但准确来说,这个其实不能称作“利⽤链”。因为其参数不是⼀个可以“利⽤”的命令,⽽仅为⼀个URL,其能触发的结果也不是命令执⾏,⽽是⼀次DNS请求。ysoserial打包成jar命令mvncleanpackage-DskipTests,刚刚入门所以用这条链作......
  • python反序列化
    这篇文章介绍python反序列化。0X00前言本篇文章搬运大佬k0rz3n的研究文章,写的特别好,存下来学习一下。0X01Python的序列化和反序列化是什么Python的序列化和反序列化是将一个类对象向字节流转化从而进行存储和传输,然后使用的时候再将字节流转化回原始的对象的一个过程。1.......
  • 序列化
          内存中的数据对象只有转换为二进制流才可以进行数据持久化和网络传输。将数据对象转换为二进制流的过程成为对象的序列化(Serialization)。反之,将二进制流恢复为数据对象的过程称为反序列化(Deserialization)。序列化需要保留充分的信息以恢复数据对象,但是为了节约存......
  • java反序列化(四) RMI反序列化
    RMIRMI(RemoteMethodInvocation),为远程方法调用,是允许运行在一个Java虚拟机的对象调用运行在另一个Java虚拟机上的对象的方法。这两个虚拟机可以是运行在相同计算机上的不同进程中,也可以是运行在网络上的不同计算机中。注册中心是一个特殊的服务端,一般与服务端在同一主机上......
  • 反序列化漏洞
    (176条消息)反序列化漏洞详解_一句话木马的博客-CSDN博客1、定义序列化是将对象转换为字符串以便存储传输的一种方式。而反序列化恰好就是序列化的逆过程,反序列化会将字符串转换为对象供程序使用。在PHP中序列化和反序列化对应的函数分别为serialize()和unserialize()。当程......
  • fastjson 1.2.24 反序列化漏洞(审计分析)
    环境JDK8u181Fastjson1.2.24POC跟进parse方法跟进到底层deserialze方法Poc中传入的dataSourceName:ldap://192.168.3.229:8084/vnSYPYwMs值这里实际对应setDataSourceName方法,调用此方法并传入ldap跟进setDataSourceName方法,这里只是简单赋值 步出......
  • java.io.Serializable(序列化)接口
     一、概念Java对象序列化的意思就是将对象的状态转化成字节流,以后可以通过这些值再生成相同状态的对象。对象序列化是对象持久化的一种实现方法,它是将对象的属性和方法转化为一种序列化的形式用于存储和传输。反序列化就是根据这些保存的信息重建对象的过程。序......