RedisTemplate操作Redis详解之连接Redis及自定义序列化

连接到Redis


使用Redis和Spring时的首要任务之一是通过IoC容器连接到Redis。为此,需要java连接器(或绑定)。无论选择哪种库,你都只需要使用一组Spring Data Redis API(在所有连接器中行为一致):org.springframework.data.redis.connection软件包及其RedisConnection与RedisConnectionFactory接口,用于处理和检索与Redis的活动连接。

RedisConnection和RedisConnectionFactory

RedisConnection提供了Redis通信和核心构建块,因为它处理与Redis后端的通信。它还会自动将基础链接库异常转换为Spring一致的DAO异常层次结构,以便您可以在不更改任何代码的情况下切换连接器,因为操作语义保持不变。

当按照上篇文档配置好Redis后,IOC会加载ConnectionFactory,我们可以直接注入,然后创建连接操作Redis。

RedisConnection提供了Redis 各大数据类型的操作API:

public interface RedisConnection extends RedisCommands, AutoCloseable {
   
     
    default RedisGeoCommands geoCommands() {
   
     
        return this;
    }
    default RedisHashCommands hashCommands() {
   
     
        return this;
    }
    default RedisHyperLogLogCommands hyperLogLogCommands() {
   
     
        return this;
    }
    default RedisKeyCommands keyCommands() {
   
     
        return this;
    }
    default RedisListCommands listCommands() {
   
     
        return this;
    }
    default RedisSetCommands setCommands() {
   
     
        return this;
    }
    default RedisScriptingCommands scriptingCommands() {
   
     
        return this;
    }
    default RedisServerCommands serverCommands() {
   
     
        return this;
    }
    default RedisStreamCommands streamCommands() {
   
     
        return this;
    }
    default RedisStringCommands stringCommands() {
   
     
        return this;
    }
    default RedisZSetCommands zSetCommands() {
   
     
        return this;
    }
}
    @Autowired
    LettuceConnectionFactory lettuceConnectionFactory;

    @Test
    void lettuceConnectionFactoryTest() {
   
     
        RedisConnection connection = lettuceConnectionFactory.getConnection();
        Boolean result = connection.set("k".getBytes(), "1".getBytes());
        System.err.println(result);

        byte[] bytes = connection.get("k".getBytes());
        assert bytes != null;
        System.err.println("k:" + new String(bytes));
    }

RedisTemplate简介

大多数用户可能会使用RedisTemplate及其相应的软件包org.springframework.data.redis.core。实际上,由于模版具有丰富的功能集,因此它是Redis模块的中心类。该模板为Redis交互提供了高级抽象,虽然RedisConnection提供了接受和返回二进制值(byte数组)的低级方法,但是模板负责序列化和连接管理,使用户无需处理此类细节。

此外,该模板提供了操作视图(根据Redis命令参考进行分组),提供了丰富的,通用的接口,用于针对某种类型或某些键(通过keyBound接口),如下表所述:

界面 描述
按键类型操作
GeoOperationsRedis的地理空间操作的,比如GEOADD,GEORADIUS...
HashOperationsRedis哈希操作
HyperLogLogOperationsRedis的HyperLogLog操作,例如PFADD,PFCONT,...
ListOperationsRedis列表操作
SetOperationsRedis设置操作
ValueOperationsRedis字符串(或值)操作
ZSetOperationsRedis zset(或排序集)操作
关键绑定操作
BoundGeoOperationsRedis键绑定地理空间操作
BoundHashOperationsRedis哈希键绑定操作
BoundKeyOperationsRedis按键绑定操作
BoundListOperationsRedis列表键绑定操作
BoundSetOperations

Redis设置键绑定操作

BoundValueOperationsRedis字符串(或值)键绑定操作
BoundZSetOperationsRedis zset(或排序集)键绑定操作

序列化器

自带序列化器

RedisTemplate大多数操作都使用基于Java的序列化器。这意味着模板编写或读取的任何对象都将通过Java进行序列化和反序列化。你可以在模板上更改序列化机制,Redis模块提供了几种实现,可在org.springframework.data.redis.serializer软件包中找到,您还可以将任何序列化器设置为null,并通过将enableDefaultSerializer属性设置为来将RedisTemplate与原始字节数组一起使用False。请注意,模板要求所有键都不为空。但是,只要基础串行器接受这些值,它们就可以为空。

从框架的角度来看,Redis中存储的数据仅为字节。尽管Redis本身支持各种类型,但在大多数情况下,它们是指数据的存储方式而不是数据的表示方式。由用户决定是否将信息转换为字符串或任何其他对象。

在Spring Data中,用户(自定义)类型和原始数据之间的转换(反之亦然)在org.springframework.data.redis.serializer包中的Redis中进行处理。

该软件包包含两种类型的序列化器,它们负责序列化过程:

  • 基于的两路串行器RedisSerializer。
  • 使用RedisElementReader和的元素读取器和写入器RedisElementWriter。

框架自带各种序列化器:

名称说明
OxmSerializer通过Spring OXM支持将其用于对象/XML映射
ByteArrayRedisSerializerByte数组序列化
GenericJackson2JsonRedisSerializer以JSON格式去存储数据,会保存序列化的对象的包名和类名,反序列化时以这个作为标示就可以反序列化成指定的对象。效率低,占用内存高
GenericToStringSerializer可以将任何对象泛化为字符串并序列化
StringRedisSerializer简单的字符串序列化
JdkSerializationRedisSerializerJDK序列化,默认用于RedisCache和RedisTemplate
Jackson2JsonRedisSerializer以JSON格式去存储数据,需要指明序列化的类Class,可以使用Object.class
自定义序列化器

RedisTemplate默认使用JDK序列化,可以使用自带其他的序列化,或者自己实现第三方序列化方式,比如:

  • google:Protobuf
  • faceBook:Thrift
  • kryo
  • hessian
  • fst
  • Jackson
  • Gson
  • FastJson
Protobuf序列化

ProtoBuf(Google Protocol Buffer)是由Google公司用于数据交换的序列结构化数据格式,具有跨平台、跨语言、可扩展特性,类型于常用的XML及JSON,但具有更小的传输体积、更高的编码、编码能力,特别适合于数据存储、网络数据传输等对存储体积、实时性要求高的领域。

优点:性能好,效率高。支持向后兼容和向前兼容。支持多种编程语言(Java,C++,python);

缺点:二进制格式导致可读性差(二进制格式)

RedisTemplate使用Protobuf

1、添加POM;

  <dependency>
            <groupId>io.protostuff</groupId>
            <artifactId>protostuff-runtime</artifactId>
            <version>1.7.4</version>
        </dependency>
        <dependency>
            <groupId>io.protostuff</groupId>
            <artifactId>protostuff-core</artifactId>
            <version>1.7.4</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

1、 实现RedisSerializer接口;

@Slf4j
public class ProtoStuffRedisSerializer<T> implements RedisSerializer<T> {
   
     

    // RuntimeSchema是一个包含业务对象所有信息的类,包括类信息、字段信息
    private static final Schema<ProtoStuffWrapper> schema = RuntimeSchema.getSchema(ProtoStuffWrapper.class);

    /**
     * 序列化:对象=》字节数组
     *
     * @param t 需要序列化的对象t
     * @return 二进制
     * @throws SerializationException 序列化异常
     */
    @Override
    public byte[] serialize(T t) throws SerializationException {
   
     
        if (t == null) {
   
     
            return null;
        }
        // 开辟了512字节缓存,用来存放业务对象序列化之后存放的地方,如果空间不足,会自动扩展扩展
        LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE);
        byte[] bytes;
        try {
   
     
            // 序列化
            bytes = ProtostuffIOUtil.toByteArray(new ProtoStuffWrapper<>(t), schema, buffer);
        } finally {
   
     
            buffer.clear();
        }
        return bytes;
    }

    /**
     * 反序列化 字节数组=》对象
     *
     * @param bytes 字节数组
     * @return 对象
     * @throws SerializationException 序列化异常
     */
    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
   
     
        if (bytes == null || bytes.length == 0) {
   
     
            return null;
        }
        try {
   
     
            ProtoStuffWrapper<T> protoStuffWrapper = new ProtoStuffWrapper<>();
            // 反序列
            ProtostuffIOUtil.mergeFrom(bytes, protoStuffWrapper, schema);
            return protoStuffWrapper.getT();
        } catch (Exception e) {
   
     
            throw new RuntimeException(e);
        }
    }

    /**
     * 序列化包装类,深度克隆,避免无法获取schema
     *
     * @param <T> 业务对象
     */
    public static class ProtoStuffWrapper<T> implements Cloneable {
   
     
        private T t;

        ProtoStuffWrapper() {
   
     
        }

        ProtoStuffWrapper(T t) {
   
     
            this.t = t;
        }

        public T getT() {
   
     
            return t;
        }

        public void setT(T t) {
   
     
            this.t = t;
        }

        @Override
        @SuppressWarnings("unchecked")
        public ProtoStuffWrapper<T> clone() {
   
     
            try {
   
     
                return (ProtoStuffWrapper<T>) super.clone();
            } catch (CloneNotSupportedException e) {
   
     
                return new ProtoStuffWrapper<T>();
            }
        }
    }
}

1、 创建RedisTemplate,设置序列化;

 /**
     * 创建RedisTemplate
     *
     * @param redisConnectionFactory 连接工厂
     * @param <T>                    值类型
     * @return RedisTemplate
     */
    @Bean(name = "redisTemplate")
    public <T> RedisTemplate<String, T> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
   
     
        RedisTemplate<String, T> redisTemplate = new RedisTemplate<>();
        // 设置连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        // String序列化对象
        RedisSerializer<String> stringRedisSerializer = RedisSerializer.string();
        // ProtoStuff序列化
        ProtoStuffRedisSerializer<T> protoStuffRedisSerializer = new ProtoStuffRedisSerializer<>();
        // 序列化配置=>Key
        redisTemplate.setKeySerializer(stringRedisSerializer); // 所有Key都设置为字符串,方便阅读
        redisTemplate.setHashKeySerializer(protoStuffRedisSerializer); //  设置Hash数据结构中的Key
        // 序列化配置=>Value
        redisTemplate.setValueSerializer(protoStuffRedisSerializer); // 所有Value
        redisTemplate.setHashValueSerializer(protoStuffRedisSerializer);  //  Hash数据结构中的Value
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

1、 添加测试实体类;

@ToString
@Data
public class User {
   
     
    String userName;
    String password;
    int age;
}

1、 添加测试类测试;

@Test
    void protoStuffTest() {
   
     
        User user = new User();
        user.setAge(20);
        user.setUserName("韩梅梅");
        user.setPassword("123456");

        redisTemplate.boundValueOps("k").set(user);
        User user1 = redisTemplate.boundValueOps("k").get();

        redisTemplate.boundHashOps("hash").putIfAbsent("kkk","vvv");
        System.err.println(user1.toString());
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/624093.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

游戏中的设计模式一

游戏开发是一个快速迭代的过程&#xff0c;代码复杂度也很高&#xff0c;借助于设计模式&#xff0c;可以帮助我们降低复杂度&#xff0c;降低系统间的耦合&#xff0c;从而高效高质的做出交付。 最近读了这本书&#xff1a;《游戏编程模式》[1]&#xff0c;很受启发&#xff…

探索Playwright:Python下的Web自动化测试革命

在如今这个互联网技术迅速发展的时代&#xff0c;web应用的质量直接关系着企业的声誉和用户的体验。因此&#xff0c;自动化测试成为了保障软件质量的重要手段之一。今天&#xff0c;我将带大家详细了解一款在测试领域大放异彩的神器——Playwright&#xff0c;并通过Python语言…

【搬砖实战】2024年了,还有人不会搭建内网穿透吗?

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;本文讲解动手自己搭建内网穿透&#xff0c;期待与你一同探索、学习、进步&#xff0c;一起卷起来叭&#xff01; 目录 一、前言内网穿透是什么&#xff1f;frp介绍&#xff1a…

Golang SDK安装

windows环境安装 1.链接: 下载地址 2.安装SDK 检查环境变量&#xff1a; 3.开启go modules,命令行执行一下命令&#xff1a; go env -w GO111MODULEon4.设置国内代理&#xff0c;命令行执行一下命令&#xff1a; go env -w GOPROXYhttps://proxy.golang.com.cn,https:/…

【Linux】进程信号(2万字)

目录 前言 一、生活角度的信号 1.1、我们来见一见信号&#xff1a; 1.2、模拟一下 kill 指令 二、信号的处理 三、产生信号的5种方法 3.1、kill命令 3.2、键盘可以产生信号 3.3、3种系统调用 3.4、软件条件 3.5、异常 四、比较 core 和 Term 五、键盘信号产生 六…

AI绘画如何变现?stablediffusion小白上手指南:2个工具+4个渠道

公司一计算机大佬&#xff0c;用AI画画一个月搞钱1w&#xff0c;画着画着都快超过本职工资了。费了点小心思整理出这篇文章&#xff0c;把搜刮来的一手经验全盘托出&#xff0c;觉得有用的友友记得点赞收藏哦&#xff01; 我有个朋友学设计的&#xff0c;今年找了大半年工作&a…

【轮转数组】力扣python

1.python切片 这里nums[:]代表列表 class Solution:def rotate(self, nums: List[int], k: int) -> None:nlen(nums)nums[:]nums[-k%n:]nums[:-k%n] 2.边pop边push 0代表插入的位置 class Solution:def rotate(self, nums: List[int], k: int) -> None:nlen(nums)fo…

OpenAi 免费GPT-4o来袭,音频视觉文本实现「大一统」

今天凌晨&#xff0c;即北京时间5月14日1点整&#xff0c;OpenAI 召开了首场春季发布会&#xff0c;CTO Mira Murati 在台上和团队用短短不到30分钟的时间&#xff0c;揭开了最新旗舰模型 GPT-4o 的神秘面纱&#xff0c;以及基于 GPT-4o 的 ChatGPT&#xff0c;均为免费使用。 …

试试这四个AI论文工具和降重技术,低成本高回报

在科研领域&#xff0c;AI写作工具如同新一代的科研利器&#xff0c;它们能够极大提高文献查阅、思路整理和表达优化的效率&#xff0c;本质上促进了科研工作的进步。AI写作工具不仅快速获取并整理海量信息&#xff0c;还帮助我们精确提炼中心思想&#xff0c;显著提升论文写作…

智能终端RK3568主板在智慧公交条形屏项目的应用,支持鸿蒙,支持全国产化

基于AIoT-3568A的智慧公交条形屏&#xff0c;可支持公交线路动态展示&#xff0c;语音到站提醒&#xff0c;减少过乘、漏乘的情况&#xff0c;有效提高了公交服务效率和质量&#xff0c;为乘客提供了更舒适、更安全和更方便的出行体验&#xff0c;为城市的发展增添了新的活力。…

WS2812B-2020 智能控制LED集成光源芯片IC

一般说明 WS2812B-2020是一款智能控制LED光源&#xff0c;它的外部采用了最新的模压封装技术&#xff0c;控制电路和RGB芯片集成在一个2020组件中。其内部包括智能数字端口数据锁存器和信号整形放大驱动电路。还包括一个精密的内部振荡器和一个电压可编程恒流控制部分&…

从零开始学习Linux(8)----自定义shell

shell从用户读入字符串“ls”&#xff0c;shell建立一个新的进程&#xff0c;然后在那个进程中运行ls程序并等待那个进程结束。然后shell读取新的一行输入&#xff0c;建立一个新的进程&#xff0c;在这个进程中运行程序&#xff0c;并等待这个进程结束。所以要写一个shell&…

iZotope RX 11 for Mac:音频修复的终极利器

在音频制作的浩瀚星海中&#xff0c;每一份声音都是珍贵的宝石&#xff0c;但往往被各种噪音、杂音所掩盖。此刻&#xff0c;iZotope RX 11 for Mac犹如一位专业的匠人&#xff0c;以其精湛的技术&#xff0c;将每一份声音雕琢至完美。 iZotope RX 11 for Mac&#xff0c;这是…

【源码】二开 欧亚版自动抢单系统源码(中、英、泰、日四语言)

二开 欧亚版自动抢单系统源码(中、英、泰、日四语言) 这个版本除了前台界面做了一些改变&#xff0c;同时功能细节上也做了一些改动。 如增加订单、充值、提现假人管理&#xff1b;增加短信开关&#xff0c;增加短信宝、阿里云、云之讯短信接口&#xff1b;增加商品匹配区间设…

男士内裤有什么牌子?2024年公认男士内裤口碑最好的品牌

对于男性来说&#xff0c;一条内裤都是可以穿好久的存在。但实际上作为贴身衣物的内裤&#xff0c;最好是3-6月就更换一次是最好的&#xff0c;如果长期不更换会使内裤的舒适性透气性降低&#xff0c;而且残留细菌无法得到清除&#xff01; 面对市面上琳琅满目的品牌和材质分类…

vscode调试Electron+ts

调试Electronjs 调试Electronjs: https://www.electronjs.org/zh/docs/latest/tutorial/debugging-vscode 调试Electronts 首先看一下&#xff0c;我的目录结构。目录结构决定了launch.json中的路径部分。我将在项目根目录下进行调试&#xff0c;项目根目录下包含electron代码…

3款游戏录屏软件,记录你的精彩瞬间!

随着科技的飞速发展&#xff0c;游戏行业迎来了前所未有的繁荣。在游戏世界中&#xff0c;录屏功能成为了一项重要的辅助功能&#xff0c;它不仅能够帮助玩家记录精彩的游戏瞬间&#xff0c;还可以用于游戏教学、解说、直播等多种场景。本文将详细介绍三款主流的游戏录屏软件&a…

如何把root账号的文件修改为tank账号

linux系统 以当前用户命令创建的目录都是root的用户并且是只读的&#xff1a; 用优盘拷贝的文件及文件夹的权限是&#xff1a; 解决方案是&#xff1a;把root账号的文件修改为tank账号 在Linux系统中&#xff0c;如果您需要将属于root用户的文件或目录的所有权更改到另一个用…

裸机工程开发调试

裸机工程开发调试 嵌入式系统的组成 嵌入式系统设备遵循自底向上的基本结构 嵌入式微处理器 嵌入式操作系统 外围硬件设备 用户应用程序 ###s5p6818系统主要资源 s5p6818是三星公司推出的64位RISC微处理器&#xff0c; 其CPU采用的是ARM CortexA53内核, 基于ARMv7和ARMv8指…

U盘打不开提示格式化怎么办?(含数据恢复及U盘修复教程)

引言&#xff1a; 随着数字化时代的发展&#xff0c;U盘已成为我们日常生活和工作中不可或缺的数据存储工具。然而&#xff0c;有时我们可能会遇到U盘突然无法打开&#xff0c;并提示需要格式化的问题。这不仅会打乱我们的工作节奏&#xff0c;还可能会导致重要数据丢失。本文…