springboot luttuc redis 集成protobuf,手动序列化反序列化

前置需知:
1.本文章和网上大部分博客配置不太一样,各位看官要分析一下自己的需求。集成protobuf 本文章主要是手动调用protobuf的序列化方法,而不是交由springboot 去做,会偏向原生java 使用方式

2.由于为了和公司其他的项目达成一致,所以版本,依赖 都尽量保证一致,所以版本需要各位看官具体决定了哈(团队使用时不同版本会有冲突)
另外:看了网上用了protostuff https://blog.csdn.net/shenTiBeiTaoKongLa/article/details/107123596可以试一下(因为我没试,可以反馈成功与否哦)。

3.考虑到其他项目使用原生的luttuce,不支持key/value 结构不一致,所以对redis key field value 都进行压缩了(关注官网变更哦,后面会支持。或者看一下sprinboot-redis的源码(sprinboot支持的),对原生的Luttuce集成一下)在这里插入图片描述
在这里插入图片描述

4.由于初期设计的.proto文件,可能存在压缩不完全的问题(后面会具体聊),大家可以见仁见智了啊,欢迎反馈

话多说了,先上配置
pom依赖如下
<protobuf.version>3.24.0</protobuf.version>

  <dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java</artifactId><version>${protobuf.version}</version> <!-- protobuf --></dependency><dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java-util</artifactId> <!--protobuf 工具类--><version>${protobuf.version}</version></dependency><!-- Spring Data Redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>${spring-boot.version}</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.11.1</version> <!-- 请检查最新版本 --></dependency>

继承RedisTemplate 对象 生成个性化RedisTemplate bean,配置序列化反序列化,自定义序列化RedisSerializer<byte[]> byteRedisSerializer = new RedisSerializer() 重写内部类是最核心的地方!

@Component
@AutoConfigureAfter(RedisAutoConfiguration.class)
@Import({RedisAutoConfiguration.class})
@Slf4j
public class ProtobufRedisTemplate extends RedisTemplate<Object, Object> {public ProtobufRedisTemplate( @Autowired() LettuceConnectionFactory lettuceConnectionFactory) {ProtobufRedisSerializer protobufRedisSerializer = new ProtobufRedisSerializer(Object.class);StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();setConnectionFactory(lettuceConnectionFactory);afterPropertiesSet();**-- 重写RedisSerializer 序列反序列化方法,直接返回数据 ,核心!!!!**RedisSerializer<byte[]> byteRedisSerializer = new RedisSerializer() {@Overridepublic byte[] serialize(Object o) throws SerializationException {if (o instanceof byte[]){return (byte[])o;}return new byte[0];}@Overridepublic byte[] deserialize(byte[] bytes) {return bytes;}};setKeySerializer(byteRedisSerializer);setValueSerializer(byteRedisSerializer);setHashKeySerializer(byteRedisSerializer);setHashValueSerializer(byteRedisSerializer);logger.warn("the Lettuce-protobuf starting success,date is -->"+ new Date());}
}

redis 工具类

@Component
@Slf4j
public class RedisUtils {@Autowiredprivate ProtobufRedisTemplate protobufRedisTemplate;/*** HashSet 并设置时间* @param key 键* @param map 对应多个键值* @param time 时间(秒)* @return true成功 false失败*/public boolean p_hmset(byte[] key, Map<byte[], byte[]> map, int time) {try {protobufRedisTemplate.opsForHash().putAll(key, map);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** HashGetAll** @return 值*/public Map<byte[], byte[]> p_hgetall(byte[] key) {Map<Object, Object> map = protobufRedisTemplate.opsForHash().entries(key);Map<byte[], byte[]> resultMap = map.entrySet().stream().collect(Collectors.toMap(entry -> (byte[]) entry.getKey(), entry -> (byte[]) entry.getValue()));return resultMap;//return protobufRedisTemplate.opsForHash().entries(key);}
}

测试的代码

        RedisData.RedisValue redisValue2 = RedisData.RedisValue.newBuilder().putValue("master_id", createRedisObject("xxxx")).putValue("item_code", createRedisObject("")).putValue("content_id", createRedisObject("xxxx")).build();final byte[] byteArray2 = redisValue2.toByteArray();//序列化Map<byte[], byte[]> test = new HashMap<>();final byte[] byteField1 = RedisData.RedisKey.newBuilder().setKey("xxxx").build().toByteArray();test.put(byteField1, byteArray);final byte[] byteField2 = RedisData.RedisKey.newBuilder().setKey("xxx").build().toByteArray();test.put(byteField2, byteArray2);byte[] bytes_key = RedisData.RedisKey.newBuilder().setKey("xxx").build().toByteArray();byte[] bytes_value = RedisData.RedisKey.newBuilder().setKey("xxx").build().toByteArray();redisUtils.p_hmset(bytes_value, test, 2592000);redisUtils.p_set(bytes_key, bytes_key, 2592000);

.proto文件数据结构如下(仅供参考):
这个是对可变的Map 进行压缩的,可能会压缩不完全
可以把map<string,RedisObject> value=1; 改成map<RedisKey,RedisObject> value=1;

syntax = "proto3";package xxxx;
import public "google/protobuf/timestamp.proto";
option optimize_for=CODE_SIZE;
option java_outer_classname = "RedisData";message RedisValue{map<string,RedisObject> value=1;
}message RedisKey{string key=1;
}message RedisObject{oneof value {string string_value = 1;int32 int_value = 2;double double_value = 3;google.protobuf.Timestamp Timestamp = 4;}
}

使用maven 将proto文件编译成java文件

 <os.detected.classifier>windows-x86_64</os.detected.classifier><build><extensions><!--主要用于获取并设置与操作系统相关的属性--><extension><groupId>kr.motd.maven</groupId><artifactId>os-maven-plugin</artifactId><version>1.6.2</version></extension></extensions><plugins><!--protobuf plugins 插件--><plugin><groupId>org.xolstice.maven.plugins</groupId><artifactId>protobuf-maven-plugin</artifactId><version>0.6.1</version><configuration><protocArtifact>com.google.protobuf:protoc:3.24:exe:${os.detected.classifier}</protocArtifact><!--默认值,proto源文件路径--><protoSourceRoot>${project.basedir}/src/main/proto</protoSourceRoot></configuration><executions><execution><goals><goal>compile</goal><goal>test-compile</goal></goals></execution></executions></plugin></plugins></build>

在这里插入图片描述
使用方式:直接copy ,当做普通的java类使用就可以了,注意要和proto文件里面的package xxxx; 路径一致,否则会报错。

效果如下
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HTML + CSS - 网页布局之一般布局浮动布局

1. 一般布局 1.1 一般布局相关参数 元素内容常常可以想像为放在一个盒子里&#xff0c;然后在周边加上内边距&#xff0c;边框和外边距&#xff0c;是盒子模型 默认一个块级区域会填充父类所有的行向空间&#xff0c;并且沿着块伸长容纳其内容&#xff0c;可以为块状体设置某…

实习项目|苍穹外卖|day10

Spring Task cron 表达式 入门案例 订单状态定时处理 通知用户支付&#xff01;通知商家完成订单&#xff01; Scheduled(cron "0 0/1 * * * ? ")public void processTimeoutOrder(){log.info("定时处理超时订单: {}", LocalDateTime.now());//答案是…

Stable Diffusion AI算法,实现一键式后期处理与图像修复魔法

在当今数字影像时代&#xff0c;后期处理技术已成为将原始图像转化为视觉上令人惊叹艺术作品的点睛之笔。随着人工智能技术的飞速发展&#xff0c;尤其是Stable Diffusion技术在图像处理领域的应用&#xff0c;图片后期处理已达到前所未有的高度&#xff0c;为摄影师、设计师及…

【STM32 HAL库】IIC通信与CubeMX配置

【STM32 HAL库】IIC通信与CubeMX配置 前言理论IIC总线时序图IIC写数据IIC读数据 轮询模式CubeMX配置应用示例AHT20初始化初始化函数读取说明读取函数 中断模式CubeMX配置状态机图fsm.caht20.c DMA模式CubeMX配置代码 前言 本文为笔者学习 IIC 通信的总结&#xff0c;基于keysk…

如何进行数字化基础设施的构建呢?

数字化基础设施的构建是一个复杂而系统的过程&#xff0c;它涉及多个方面和层次的建设。以下是一个详细的构建步骤和关键点&#xff1a; 一、明确建设目标和需求 战略规划&#xff1a;结合企业的长期发展目标&#xff0c;明确数字化基础设施建设的总体方向和具体目标。需求分析…

LabVIEW中AVI帧转图像数据

在LabVIEW中&#xff0c;有时需要将AVI视频文件的帧转换为图像数据进行进一步处理。下面详细讲解了如何从AVI视频提取单帧并将其转换为图像数据集群&#xff0c;以便与其他图像处理VI兼容。 问题背景&#xff1a; 用户已经拥有能够处理JPEG图像数据集群的VI&#xff0c;现在希…

房产销售系统:SpringBoot技术应用案例

第二章关键技术的研究 2.1相关技术 房产销售系统是在Java MySQL开发环境的基础上开发的。Java是一种服务器端脚本语言&#xff0c;易于学习&#xff0c;实用且面向用户。全球超过35&#xff05;的Java驱动的互联网站点使用Java。MySQL是一个数据库管理系统&#xff0c;因为它的…

学习大数据DAY58 增量抽取数据表

作业 1 SQL 优化的常见写法有哪些 - 面试经常被问 使用索引&#xff1a;合理创建和使用索引是提高查询效率的关键。索引可以加速数据的检 索速度&#xff0c;但是索引也会占用额外的存储空间&#xff0c;并且在插入、删除和更新操作时会 有额外的开销。 避免全表扫描&…

线段树介绍及线段树的使用场景

1.线段树用来解决什么问题 假如说你有一个数组&#xff0c;数组下标为 0-1000&#xff0c;然后对外提供一些方法&#xff0c; 1.1比如说你对外提供add方法&#xff0c;add方法&#xff08;1,200,6&#xff09;&#xff0c;请你把从1 到 200 位置所有的值 加上6 1.2更新&…

Qt与MQTT交互通信

MQTT全称是&#xff08;Message Queuing Telemetry Transport&#xff09;&#xff0c;即消息队列遥测传输协议 是一种基于发布/订阅&#xff08;Publish/Subscribe&#xff09;模式的轻量级通讯协议&#xff0c;并且该协议构建于TCP/IP协议之上&#xff0c;常用于互联网中&am…

Zabbix自定义监控项与触发器

当我们需要获取某台主机上的数据时&#xff0c;直接利用 zabbix 提供的模板可以很方便的获得需要的数据,但是有些特别的数据&#xff0c;利用这些现有的模板或监控项是无法实现的&#xff0c;例如网站状态信息的监控、mysql数据库主从状态等信息。这是就需要自己定义键值和监控…

【Unity】在Unity 3D中使用Spine开发2D动画

文章目录 内容概括前言下载安装 Spine Pro导入Unity插件Spine动画导入Unity使用展现动画效果展现 内容概括 本文主要讲解 Spine Pro 免&#xff08;破&#xff09;费&#xff08;解&#xff09;版的安装&#xff0c;以及如何将动画导入到Unity中使用。 前言 通常要用 Spine …

基于鸿蒙API10的RTSP播放器(七:亮度调节功能测试)

目标&#xff1a; 当我的手指在设备左方进行上下移动的时候&#xff0c;可以进行屏幕亮度的调节&#xff0c;在调节的同时&#xff0c;有实时的调节进度条显示 步骤&#xff1a; 界面逻辑&#xff1a;使用Stack() 组件&#xff0c;完成音量图标和进度条的组合显示&#xff0c…

Unity 粒子系统参数说明

一、Particle System 1. Duration&#xff08;持续时间&#xff09; 粒子系统运行一次所需的时间。它决定粒子系统持续播放的时间长度。 2. Looping&#xff08;循环播放&#xff09; 如果启用&#xff0c;粒子系统将在播放完一次后自动重新开始播放&#xff0c;直到你停止它…

3. 进阶指南:自定义 Prompt 提升大模型解题能力

怎么判断 Prompt 的好坏&#xff0c;有什么问题有着标准答案么&#xff1f; 答&#xff1a;让大模型求解数学问题。 李宏毅老师的 HW4 正好提到了有关数学问题的 Prompt&#xff0c;所以我决定中间插一篇这样的文章。通过本文你将&#xff1a; 了解各种 Prompt 如何影响大型语言…

javase复习day22泛型、set、数据结构

泛型 package MyGenerics;import java.util.ArrayList; import java.util.Iterator;public class GenericsTest1 {public static void main(String[] args) {//没有泛型的情况ArrayList list new ArrayList();//所有数据都被认为是Object类型&#xff0c;都可以加入集合中list…

记录开发一个英语听力训练网站

背景 在当前全球经济衰退的背景下&#xff0c;IT相关的工作在国内的竞争也是越来越激烈&#xff0c;为了能够获得更多的可能性&#xff0c;英语的学习也许能为程序员打开一扇新的窗户&#xff0c;比如很多远程的工作尤其是国际化背景的工作团队&#xff0c;英语的协作沟通是必…

uniapp 发布苹果IOS详细流程,包括苹果开发者公司账号申请、IOS证书、.p12证书文件等

记录一下uniapp发布苹果IOS的流程。 一、苹果开发者公司账号申请 1、邓白氏编码申请&#xff08;先申请公司邓白氏编码&#xff0c;这一步需要1-2周&#xff0c;没有这个编码苹果开发者没法申请&#xff0c;已有编码的跳过此步骤&#xff09;&#xff1a; 1&#xff09;联系苹…

[机器学习]决策树

1 决策树简介 2 信息熵 3 ID3决策树 3.1 决策树构建流程 3.2 决策树案例 4 C4.5决策树 5 CART决策树&#xff08;分类&回归&#xff09; 6 泰坦尼克号生存预测案例 import pandas as pd from sklearn.model_selection import train_test_split from sklearn.tree import …

链表的快速排序(C/C++实现)

一、前言 大家在做需要排名的项目的时候&#xff0c;需要把各种数据从高到低排序。如果用的快速排序的话&#xff0c;处理数组是十分简单的。因为数组的存储空间的连续的&#xff0c;可以通过下标就可以简单的实现。但如果是链表的话&#xff0c;内存地址是随机分配的&#xf…