一篇文章带你完全明白序列化与反序列化的过程
背景
最近项目中要按照对象方式进行存取,使用时再拿出来,于是我们就要学习序列化和反序列化的相关知识。
基于我们的项目,按照课表进行推课的时候,课表中当前课程结束的时候,将执行的颗粒存到redis中。
步骤
概念
序列化和反序列化是计算机科学中用于数据存储和传输的重要概念。
序列化(Serialization)
是将数据结构或对象转换成一种可存储或可传输格式的过程。在序列化后,数据可以被写入文件、发送到网络或存储在数据库中,以便在需要时可以再次还原成原始的数据结构或对象。序列化的过程通常涉及将数据转换成字节流或类似的格式,使其能够在不同平台和编程语言之间进行传输和交换。
反序列化(Deserialization)
是序列化的逆过程,即将序列化后的数据重新还原成原始的数据结构或对象。反序列化是从文件、网络数据或数据库中读取序列化的数据,并将其转换回原始形式,以便在程序中进行使用和操作。
使用场景
序列化和反序列化在许多场景中都非常有用,例如:
数据存储:将程序中的数据保存到文件或数据库中,以便在以后重新加载和使用。
网络通信:在网络上传输数据时,需要将数据序列化为字节流,以便在接收端进行反序列化。
分布式系统:在分布式系统中,不同计算节点之间需要通过序列化和反序列化来交换数据。
进程间通信:不同进程之间通信时,数据需要在序列化和反序列化之间进行转换。
常见的序列化格式包括 JSON(JavaScript Object Notation)、XML(eXtensible Markup Language)、Protocol Buffers、MessagePack等。每种格式有其优势和适用场景,选择合适的序列化格式取决于具体的应用需求。
理解原理小Demo(可以理解成编码解码,很简单的)
import java.io.*; public class Serialization { private static final File SAVE_FILE = new File("D:" + File.separator + "demo.Class"); public static void saveObject(Object object) throws IOException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(SAVE_FILE)); oos.writeObject(object); // 序列化 oos.close(); } public static Object loadObject() throws Exception { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(SAVE_FILE)); Object obj = ois.readObject(); // 反序列化 ois.close(); return obj; } public static void main(String[] args) throws Exception { saveObject(new Class(new Person("p",11),"class",12));// 序列化 Class c = (Class)loadObject(); System.out.println(c); // 反序列化 } public static class Person implements Serializable { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } } public static class Class implements Serializable{ private Person person; private String name; private int age; public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Class{" + "person=" + person + ", name='" + name + '\'' + ", age=" + age + '}'; } public Class(Person person) { this.person = person; } public Class(Person person, String name, int age) { this.person = person; this.name = name; this.age = age; } } }
可以通过打断点的方式查看对象的展示情况
将内存中的对象通过序列化的方式存储到本地的某个文件中
然后调用另外一个方法从本地文件中拿到对象放置到内存中
这样我们就了解了序列化和反序列的概念,下面看看在redis是如何实现序列化和反序列化的吧。
使用redis步骤
建立springboot项目
引入坐标
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
建类
在这里插入代码片
package com.example.redis.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig { /** * RedisTemplate配置 */ @Bean public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) { // 设置序列化 Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 配置redisTemplate RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(lettuceConnectionFactory); RedisSerializer<?> stringSerializer = new StringRedisSerializer(); // key序列化 redisTemplate.setKeySerializer(stringSerializer); // value序列化 redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); // Hash key序列化 redisTemplate.setHashKeySerializer(stringSerializer); // Hash value序列化 redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } }
server: port: 8081 spring: redis: host: **redis.***d.tech port: 6379 password: *** database: 0 timeout: 300000ms #连接超时 jedis: pool: max-active: 8 #连接池最大的连接数 max-wait: -1ms #连接池最大的阻塞等待时间(负值表示没有限制) max-idle: 500 #连接池最大的空闲连接
package com.example.redis.Entity; import lombok.Data; import java.io.Serializable; import java.util.Date; @Data public class UserInfo implements Serializable { /** * id */ private Integer id; /** * 姓名 */ private String name; /** * 创建时间 */ private Date createTime; }
package com.example.redis.utils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; /** * @ClassName RedisUtils * @Description * @Author Lizhou * @Date 2020-10-22 10:10:10 **/ @Slf4j @Component public class RedisUtils { @Autowired private RedisTemplate<String, Object> redisTemplate; /** * 根据key读取数据 */