当前位置: 首页 > news >正文

SpringDataJpa-字段加解密存储

SpringDataJpa-字段加解密存储

    • 背景
    • 场景
    • 实现
      • 类型转换器
        • 实体类修改
      • Crypto 注解
      • AOP
    • 目前可使用场景
    • 注意

背景

遇到一个需求,对数据库中的某些字段进行加密存储,但是在各个服务流转中,需要是解密状态的。框架使用的是JPA。

Spring 提供了 AttributeConverter<T,R> 用来将实体属性与数据库字段之间的逻辑转换。换日期格式转换这种。但是我们这边需要改变类型,只需要改变类型的值。

但是使用原生SQL的时候用加密字段进行查询的化,是不会使用类型转换器的。所以我这里增加了一个注解,来拦截标有该注解的参数,然后将参数的值进行修改,然后再进行查询。这里实现的化使用的是 AOP

场景

  • 使用实体类进行查询,插入,更新,删除(HQL
    • 使用加密字段进行查询的(使用类型转换器实现)
    • 返回为实体类 (使用类型转换器实现)
  • 使用原生sql 进行查询,插入,更新,删除
    • 返回出来的是 map 结构(需要单独处理)
    • 返回为实体类 (使用类型转换器实现)
    • 使用加密字段进行查询的(AOP + 注解实现

实现

类型转换器

实现AttributeConverter

@Slf4j
public class CryptoConvert implements AttributeConverter<String,String> {/*** 存入数据库前进行的转化操作* @param attribute* @return*/@Overridepublic String convertToDatabaseColumn(String attribute) {String encode = CryptoUtil.encode(attribute);log.info("oldValue:{},newValue:{}",attribute,encode);return encode;}/*** 取出数据库后进行的转化操作* @param dbData* @return*/@Overridepublic String convertToEntityAttribute(String dbData) {String decode = CryptoUtil.decode(dbData);log.info("oldValue:{},newValue:{}",dbData,decode);return decode;}
}
实体类修改
@Column(name="remark")
// 增加类型转换器,标注该字段需要使用类型转换器处理
@Convert(converter = CryptoConvert.class)
private java.lang.String remarks;

Crypto 注解

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Crypto {
}

AOP

尝试使用@Before但是不能修改参数的值,所以这里使用@Around

@Slf4j
@Component
@Aspect
public class CryptoAspect {/*** 针对带有@Crypto注解的参数进行加密* @param joinPoint* @return* @throws Throwable*/@Around(value = "execution(* *(..,@Crypto (String),..))")public Object encrypt(ProceedingJoinPoint joinPoint) throws Throwable {MethodSignature signature = (MethodSignature) joinPoint.getSignature();Annotation[][] parameterAnnotations = signature.getMethod().getParameterAnnotations();Object[] oldArgs = joinPoint.getArgs();Object[] newArgs = Arrays.copyOf(oldArgs, oldArgs.length);for (int i = 0; i < newArgs.length; i++) {if (Objects.isNull(newArgs[i])) {continue;}if(!(newArgs[i] instanceof String)){continue;}Annotation[] parameterAnnotation = parameterAnnotations[i];if (ArrayUtils.isEmpty(parameterAnnotation)) {continue;}for (Annotation annotation : parameterAnnotation) {if (Crypto.class.equals(annotation.annotationType())) {String str = (String) newArgs[i];String encode = CryptoUtil.encode(str);newArgs[i] = encode;}}}log.info("oldArgs:{} newArgs:{}",oldArgs,newArgs);// 使用解密后的参数调用对应方法return joinPoint.proceed(newArgs);}
}

目前可使用场景

// 1.JPA 使用方法名操作数据库                  remarks 为需要加密查询的字段 
List<Model> findByRemarks(@Param(value = "remarks") String remarks);// 2.JPA 使用 @Query 注解并使用 HQL 操作数据库   remarks 为需要加密查询的字段 
@Query("select C FROM Model C where C.remarks = ?1")
List<Model> findByRemarks2(@Param(value = "remarks") String remarks);// 3.JPA 使用 @Query 注解并使用 原生SQL 操作数据库   remarks 为需要加密查询的字段  (hibernate 查出数据库时也会使用类型转换器所以不再单独解密)
@Query(value = "select * from t_model where remark = ?1",nativeQuery = true)
List<Model> findByRemarks3(@Crypto @Param(value = "remarks") String remarks);// 4.使用 Query + HQL   及可实现(hibernate 查出数据库时也会使用类型转换器所以不再单独解密)
@Override
public List<Model> getRemarks2(String remarks) {Query query = em.createQuery("select C FROM Model C where C.remarks = ?1",AccountBindHistory.class);query.setParameter(1, remarks);List<Model> resultList = query.getResultList();return resultList;
}// 5.使用 Query + SQL  这个需要在入口处添加@Crypto 及可实现(hibernate 查出数据库时也会使用类型转换器所以不再单独解密)
@Override
public List<Model> getRemarks(@Crypto String remark) {Query query = em.createNativeQuery("select * from t_model where remark = ?",AccountBindHistory.class);query.setParameter(1, remark);List<Model> resultList = query.getResultList();return resultList;
}// em.createNativeQuery 在创建Query的时候需要指定操作的映射类型// 6.Spring-data-rest 生成的接口也支持自动加解密

注意

  1. 加密方式需要使用**对称加密,**也就是可以将明文转换出来的算法。
  2. 数据库中已有的数据需要进行处理,也就是需要加密。这样可以保证查询是与后入库的数据都能正常解密,

相关文章:

SpringDataJpa-字段加解密存储

SpringDataJpa-字段加解密存储 背景场景实现类型转换器实体类修改 Crypto 注解AOP 目前可使用场景注意 背景 遇到一个需求&#xff0c;对数据库中的某些字段进行加密存储&#xff0c;但是在各个服务流转中&#xff0c;需要是解密状态的。框架使用的是JPA。 Spring 提供了 Attri…...

python03-保留字、标识符;变量、常量;数据类型、数据类型之间的转化

一、保留字 VS 标识符 1-1、35个保留字 保留字&#xff0c;严格区分大小写&#xff01; 查询保留字&#xff1a; 1-2、标识符 常量&#xff1a;python中没有明确的定义常量的关键字&#xff0c;常量的值在程序运行过程中不允许修改&#xff01; 二、变量 VS 常量 2-1、变量 变…...

投影互动装置入驻,科普基地学习体验再上新台阶!

数字科技的迅猛进步极大地充盈了人们的日常生活&#xff0c;这一变革在主题乐园与科普教育基地等场所尤为显著。在这些地方&#xff0c;投影互动装置引领我们穿梭于光影构建的奇妙世界。特别是互动投影墙&#xff0c;它赋予观众前所未有的交互体验。那么&#xff0c;这种技术究…...

socket编程UDP-实现滑动窗口机制与累积确认GBN

在下面博客中&#xff0c;我介绍了利用UDP模拟TCP连接、按数据包发送文件的过程&#xff0c;并附上完整源码。 socket编程UDP-文件传输&模拟TCP建立连接脱离连接&#xff08;进阶篇&#xff09;_udp socket发送-CSDN博客 下面博客实现了停等机制。 socket编程UDP-实现停…...

乐观锁与悲观锁的概念

在多线程或多进程并发访问同一资源的情况下&#xff0c;为了防止数据的不一致性和竞态条件&#xff0c;常常需要使用锁机制来控制并发访问。锁机制大致可以分为 乐观锁&#xff08;Optimistic Locking&#xff09;和 悲观锁&#xff08;Pessimistic Locking&#xff09;。这两种…...

考研数学【线性代数基础box(数二)】

本文是对数学二线性代数基础进行总结&#xff0c;一些及极其简单的被省略了&#xff0c;代数的概念稀碎&#xff0c;不如高数关联性高&#xff0c;所以本文仅供参考&#xff0c;做题请从中筛选&#xff01; 本文为初稿&#xff0c;后面会根据刷题和自己的理解继续更新 高数&a…...

游戏引擎学习第45天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾 我们刚刚开始研究运动方程&#xff0c;展示了如何处理当人物遇到障碍物时的情况。有一种版本是角色会从障碍物上反弹&#xff0c;而另一版本是角色会完全停下来。这种方式感觉不太自然&#xff0c;因为在游戏中&#xff0c;…...

基于 mzt-biz-log 实现接口调用日志记录

&#x1f3af;导读&#xff1a;mzt-biz-log 是一个用于记录操作日志的通用组件&#xff0c;旨在追踪系统中“谁”在“何时”对“何事”执行了“何种操作”。该组件通过简单的注解配置&#xff0c;如 LogRecord&#xff0c;即可实现接口调用的日志记录&#xff0c;支持成功与失败…...

无人设备之RTK地面基站篇

一、定义与功能 RTK地面基站是一种通过差分定位技术来实现GPS等全球导航卫星系统信号精确定位的设备。它通过与无人设备上的流动站进行实时数据通信&#xff0c;利用载波相位差分原理&#xff0c;消除卫星定位过程中的大部分公共误差&#xff0c;如卫星轨道误差、电离层延迟、对…...

TMS320C55x DSP芯片结构和CPU外围电路

第2章 DSP芯片结构和CPU外围电路 文章目录 第2章 DSP芯片结构和CPU外围电路TMS320C55x处理器的特点TMS320c55x CPU单元指令缓冲(Instruction Buffer Unit) I单元程序流程(Program Flow Unit) P单元地址数据(Address-data Flow Unit) A单元数据计算(Data Computation Unit) D单元…...

【CC2530开发基础篇】继电器模块使用

一、前言 1.1 开发背景 本实验通过使用CC2530单片机控制继电器的吸合与断开&#xff0c;深入了解单片机GPIO的配置与应用。继电器作为一种常见的电气控制元件&#xff0c;广泛用于自动化系统中&#xff0c;用于控制大功率负载的开关操作。在本实验中&#xff0c;将通过GPIO口…...

3D 生成重建035-DiffRF直接生成nerf

3D 生成重建035-DiffRF直接生成nerf 文章目录 0 论文工作1 论文方法2 实验结果 0 论文工作 本文提出了一种基于渲染引导的三维辐射场扩散新方法DiffRF&#xff0c;用于高质量的三维辐射场合成。现有的方法通常难以生成具有细致纹理和几何细节的三维模型&#xff0c;并且容易出…...

安宝特分享 | AR技术助力医院总院与分院间的远程面诊

随着科技的迅猛发展&#xff0c;增强现实&#xff08;AR&#xff09;技术在各行各业的应用愈发广泛&#xff0c;特别是在医疗领域&#xff0c;其潜力和价值正在被不断挖掘。在现代医疗环境中&#xff0c;患者常常面临“看病难、看病远、看病急”等诸多挑战&#xff0c;而安宝特…...

【功能安全】硬件常用安全机制

目录 安全机制分类: ECC内存保护: 看门狗定时器WDT 看门狗的诊断覆盖率 程序流监控 软件自检<...

linux上qt打包(二)

sudo apt install git 新建一个文件夹 名为xiazai&#xff0c; chmod -R 777 xiazai cd xiazai 并进入这个文件夹&#xff0c;然后clone git clone https://github.com/probonopd/linuxdeployqt.git 此处可能要fanQiang才能下 cd linuxdeployqt文件夹 下载平台需要的…...

Vue3 左右2栏的宽度 比例resize

Vue3, 页面左右2栏布局&#xff0c;用vue-resizer.页面效果如下图。 安装 npm i vue-resizer引入 import { DragCol, DragRow, ResizeCol, ResizeRow, Resize } from vue-resizer<DragCol height"100%" width"100%" :leftPercent"15">…...

企业车辆管理系统(源码+数据库+报告)

一、项目介绍 352.基于SpringBoot的企业车辆管理系统&#xff0c;系统包含两种角色&#xff1a;管理员、用户,系统分为前台和后台两大模块 二、项目技术 编程语言&#xff1a;Java 数据库&#xff1a;MySQL 项目管理工具&#xff1a;Maven 前端技术&#xff1a;Vue 后端技术&a…...

LeetCode 1847.最近的房间:有序集合

【LetMeFly】1847.最近的房间&#xff1a;有序集合 力扣题目链接&#xff1a;https://leetcode.cn/problems/closest-room/ 一个酒店里有 n 个房间&#xff0c;这些房间用二维整数数组 rooms 表示&#xff0c;其中 rooms[i] [roomIdi, sizei] 表示有一个房间号为 roomIdi 的…...

C05S07-Tomcat服务架设

一、Tomcat 1. Tomcat概述 Tomcat也是一个Web应用程序&#xff0c;具有三大核心功能。 Java Servlet&#xff1a;Tomcat是一个Servlet容器&#xff0c;负责管理和执行Java Servlet、服务端的Java程序&#xff0c;处理客户端的HTTP请求和响应。Java Server&#xff1a;服务端…...

Vscode搭建C语言多文件开发环境

一、文章内容简介 本文介绍了 “Vscode搭建C语言多文件开发环境”需要用到的软件&#xff0c;以及vscode必备插件&#xff0c;最后多文件编译时tasks.json文件和launch.json文件的配置。即目录顺序。由于内容较多&#xff0c;建议大家在阅读时使用电脑阅读&#xff0c;按照目录…...

mac电脑可以使用的模拟器

BlueStacks Air 推荐-》亲测可用 BlueStacks Air https://www.bluestacks.com 支持macOS/Windows&#xff0c;刚新增了对Apple Silicon系列M芯片的支持 GameLoop https://www.gameloop.com/ 支持 macOS/Windows Genymotion https://www.genymotion.com/ 支持Android/macO…...

vertx idea快速使用

目录 1.官网下载项目 2.修改代码 2.1拷贝代码方式 为了能够快速使用&#xff0c;我另外创建一个新的maven项目&#xff0c;将下载项目的src文件和pom文件拷贝到新建的maven项目。 2.2删除.mvn方式 3.更新配置 4.配置application 5.idea启动项目 1.官网下载项目 从vert…...

selenium 在已打开浏览器上继续调试

关闭浏览器&#xff0c;终端执行如下指令&#xff0c;--user-data-dir换成自己的User Data路径 chrome.exe --remote-debugging-port9222 --user-data-dir"C:\Users\xxx\AppData\Local\Google\Chrome\User Data" 会打开浏览器&#xff0c;打开百度&#xff0c;如下状…...

RequestContextHolder 与 HttpServletRequest 的联系

1. 什么是 RequestContextHolder&#xff1f; RequestContextHolder 是 Spring 框架 提供的一个工具类&#xff0c;用于在当前线程中存储和获取与请求相关的上下文信息。它是基于 ThreadLocal 实现的&#xff0c;能够保证每个线程独立存储和访问请求信息。 与 HttpServletReq…...

力扣hot100——普通数组

53. 最大子数组和 class Solution { public:int maxSubArray(vector<int>& nums) {int n nums.size();int ans nums[0];int sum 0;for (int i 0; i < n; i) {sum nums[i];ans max(ans, sum);if (sum < 0) sum 0;}return ans;} }; 最大子数组和&#xf…...

本地部署大模型QPS推理测试

目录 1、测试环境1.1、显卡1.2、模型1.3、部署环境1.3.1、docker1.3.2、执行命令 2、测试问题2.1、20字左右问题2.2、50字左右问题2.3、100字左右问题 3、测试代码3.1、通用测试代码3.2、通用测试代码&#xff08;仅供参考&#xff09; 4、测试结果4.1、通用测试结果4.2、RAG测…...

内存、硬盘、DRAM、FLASH

内存 内存是计算机系统中用于临时存储和快速存取当前正在处理的数据和指令的组件&#xff0c;属于临时存储设备&#xff0c;它在计算机运行时用于存储活跃的程序和数据。内存的性能直接影响计算机的处理速度和响应能力。 内存的类型主要分为&#xff1a; DRAM&#xff08;动态随…...

全景图转6面体图 全景图与6面体图互转

目录 图片转360度全景中心图 依赖项: 库的使用方法: 源代码: 全景图拆成6面体图: 全景图,转6面体,再转全景图: 图片转360度全景中心图 原图: 效果图: 依赖项: pip install py360convert pip install numpy==2.2 库的使用方法: https://g...

【psutil模块02】Python运维模块之系统进程管理方法

系统进程管理方法 获取当前系统的进程信息&#xff0c;包括进程的启动时间、查看或设置CPU亲和度、内存使用率、IO信息、socket连接、线程数等。 1.进程信息 psutil.pids()获取所有PID,使用psutil.Process()接收单个进程的PID&#xff0c;获取进程名、路径、状态、系统资源等…...

Java-08

类的抽象是将类的实现和使用分离, 而类的封装是将实现的细节封装起来并且对用户隐藏,用户只需会用就行。 类的合约指的是从类外可以访问的方法和数据域的集合以及与其这些成员如何行为的描述 isAlive()方法的返回值类型为布尔型&#xff08;Boolean&#xff09;。这个方法用于…...

四轴用的无刷电机到底是属于直流电机还是交流电机?

四轴用的无刷电机因其高效、稳定、体积小巧等特点&#xff0c;成为了广泛应用的动力系统之一。尽管其名称中包含“直流”二字&#xff0c;但无刷电机到底是属于直流电机还是交流电机&#xff0c;这一问题常常引发人们的探讨与困惑。 一、无刷电机的工作原理 首先&#xff0c;…...

Redis中的Hot key排查和解决思路

什么是Hot key Hot key其实就是被频繁访问的key&#xff0c;比普通的key访问量要高于十倍或者几十倍不等。例如&#xff1a; QPS集中在特定的Key&#xff1a;实例的总QPS&#xff08;每秒查询率&#xff09;为10,000&#xff0c;而其中一个Key的每秒访问量达到了7,000。带宽使…...

CMake 保姆级教程(上)

整理自 视频 【CMake 保姆级教程【C/C】】 https://www.bilibili.com/video/BV14s4y1g7Zj/?p5&share_sourcecopy_web&vd_source6eb8f46d194c5ef9f89d3331f623a9c3 1、cmake简介 源文件&#xff08;.cpp / .c&#xff09;要经过 工具链 1.1 工具链 1、预处理&#…...

C++类模板的应用

template <class T> class mylist{ public: // 这是一个链表的节点 struct Link{ T val; Link* next; } 增 &#xff1a;insert(T val) 在链表中创建新节点&#xff0c;节点上保存的数据为 val 删&#xff1a;remove(T val) 移除链表中数据为 val 的节点 改: operator[](…...

Ubuntu 18.04无有线图表且无法设置有线网络

问题背景&#xff1a; 今天在登陆自己的虚拟机Ubuntu系统的时候突然出现 有线连接无法连接的问题&#xff0c;有线连接的图标变为没有了&#xff0c;无法点击网络菜单的Setting模块选项。我的虚拟机有线网络连接方式是NAT方式。 没有如下有线连接图标 解决方法&#xff1a; …...

QoS分类和标记

https://zhuanlan.zhihu.com/p/160937314 1111111 分类和标记是识别每个数据包优先级的过程。 这是QoS控制的第一步&#xff0c;应在源主机附近完成。 分组通常通过其分组报头来分类。下图指定的规则仔细检查了数据包头 &#xff1a; 下表列出了分类标准&#xff1a; 普通二…...

企业内训|阅读行业产品运营实战训练营-某运营商数字娱乐公司

近日&#xff0c;TsingtaoAI公司为某运营商旗下数字娱乐公司组织的“阅读行业产品运营实战训练营”在杭州落下帷幕。此次训练营由TsingtaoAI资深互联网产品专家程靖主持。该公司的业务骨干——来自内容、市场、业务、产品与技术等跨部门核心岗位、拥有8-10年实战经验的中坚力量…...

杭州乘云联合信通院发布《云计算智能化可观测性能力成熟度模型》

原文地址&#xff1a;杭州乘云联合中国信通院等单位正式发布《云计算智能化可观测性能力成熟度模型》标准 2024年12月3日&#xff0c;由全球数字经济大会组委会主办、中国信通院承办的 2024全球数字经济大会 云AI计算创新发展大会&#xff08;2024 Cloud AI Compute Ignite&…...

SimAI万卡集群模拟器,LLM大模型训练通信计算模拟

SimAI&#xff0c;是阿里巴巴构建的一个统一的模拟器&#xff0c;旨在大规模精确有效地模拟LLM训练过程。通过将训练框架、内核计算和集体通信库有选择地高保真集成到仿真过程中&#xff0c;SimAI在仿真中实现了高精度。 简单点来说&#xff0c;SimAI就是模拟&#xff0c;大模…...

Axure9设置画布固定

在使用AxureRP9设计原型时&#xff0c;如果遇到画布在拖动时变得难以控制&#xff0c;可以尝试在Windows系统中通过‘文件’>‘首选项’&#xff0c;或在Mac系统中通过‘AxureRP9’>‘偏好设置’进行设置&#xff0c;以稳定画布的行为。 现象 页面底层的画布&#xff0…...

window.getSelection() 获取划线内容并实现 dom 追随功能

功能&#xff1a;鼠标对一段文本中某些文字进行划线之后&#xff0c;需要在当前划线文本处出现一个功能按钮显示对划线内容进行操作&#xff0c;比如收藏、添加样本库等功能。 一、需要了解的鼠标事件对象属性 给 dom 元素注册鼠标事件之后&#xff0c;会有 event 属性&#…...

mybatis-plus超详细讲解

mybatis-plus &#xff08;简化代码神器&#xff09; 地址&#xff1a;https://mp.baomidou.com/ 目录 mybatis-plus 简介 特性 支持数据库 参与贡献 快速指南 1、创建数据库 mybatis_plus 2、导入相关的依赖 3、创建对应的文件夹 4、编写配置文件 5、编写代码 …...

浏览器可以直接请求 websocket

一、原生支持 浏览器原生支持 WebSocket 协议&#xff0c;这使得开发者可以直接在 JavaScript 代码中使用 WebSocket 来建立与服务器的双向通信通道。 const socket new WebSocket("ws://localhost:8080");socket.addEventListener("open", function (e…...

* 和 .* 的区别(MATLAB)

在 MATLAB 中&#xff0c;* 和 .* 都是用来进行乘法操作的运算符&#xff0c;但它们有不同的应用场景。我们将从数学和编程的角度详细解析这两者的区别&#xff0c;并且讲解 MATLAB 中 . 运算符的其他常见用法。 1. * 和 .* 的区别 *&#xff1a;矩阵乘法&#xff08;线性代数…...

51c视觉~合集30

我自己的原文哦~ https://blog.51cto.com/whaosoft/12059371 #SaRA 修改一行代码就能实现高效微调&#xff01;上海交大&腾讯开源&#xff1a;兼顾原始生成和下游任务 仅修改一行训练代码即可实现微调过程。 文章链接&#xff1a;https://arxiv.org/pdf/2409.06633 …...

JVM虚拟机总揽

为什么 Java 要在虚拟机里运行&#xff1f; 先说结论&#xff1a; 可以一次编译&#xff0c;在各个硬件平台如 Windows_x64、Linux_aarch64&#xff09;都可以执行建立一个托管环境&#xff08;Managed Runtime&#xff09;&#xff0c;这个托管环境能够代替我们处理一些代码…...

PCL点云库入门——PCL库可视化之PCLVisualizer类显示复杂点云信息等(持续更新)

1、PCLVisualizer类可视化 PCLVisualizer类作为PCL库可视化到的高级功能&#xff0c;不仅支持点云等数据的可视化&#xff0c;还提供了丰富的交互功能和自定义选项&#xff0c;如颜色调整、视角切换、标注添加等。用户可以通过PCLVisualizer类轻松实现复杂的数据分析和处理任务…...

Hugface国内镜像

问题&#xff1a; urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(hosthuggingface.co, port443): Max retries exceeded with url: /Salesforce/blip-image-captioning-base/resolve/main/preprocessor_config.json (Caused by ProxyError(Cannot connect to proxy.,…...

Vue3 重置ref或者reactive属性值

需要重新定义一个对象绑定复制给原对象 。 实例代码: const data () > ({groupId: ,groupCode: ,groupName: ,groupType: ,});const formData ref(data());//重置对象值 const reset()>{Object.assign(formData, data()…...

前端的Python入门指南(完):错误和异常处理策略及最佳实践

《前端的 Python 入门指南》系列文章&#xff1a; &#xff08;一&#xff09;&#xff1a;常用语法和关键字对比&#xff08;二&#xff09;&#xff1a;函数的定义、参数、作用域对比&#xff08;三&#xff09;&#xff1a;数据类型对比 - 彻底的一切皆对象实现和包装对象异…...