mybatis、mybatis-plus插件开发,实现数据脱敏功能

首先说一下mybatis中四大组件的作用,下面开发的插件拦截器会使用
四大组件Executor、StatementHandler、ParameterHandler、ResultSetHandler


Executor:

Executor 是 MyBatis 中的执行器,负责 SQL 语句的执行工作。它通过调度 StatementHandler、ParameterHandler 和 ResultSetHandler 来完成 SQL 的增删改查操作。Executor 管理事务和缓存,可以是 SimpleExecutor、ReuseExecutor、BatchExecutor 或在开启二级缓存时的 CachingExecutor。

ParameterHandler:

ParameterHandler 用于处理 SQL 语句的参数设置。它将 Mapper 接口方法的参数封装,并负责将这些参数值传递给 PreparedStatement,以便进行预编译和执行。ParameterHandler 通过 TypeHandler 接口完成 Java 类型到 JDBC 类型的转换。

ResultSetHandler:

ResultSetHandler 负责处理 SQL 执行后的返回结果集(ResultSet)。它将结果集转换并映射到 Java 对象,完成从数据库字段到 Java 实体属性的映射工作。ResultSetHandler 能够处理多种结果集的复杂映射关系。

StatementHandler:

StatementHandler 是 MyBatis 中的语句处理器,它是四大对象的核心,起到承上启下的作用。StatementHandler 负责使用 JDBC 的 Statement(包括 PreparedStatement 和 CallableStatement)执行实际的数据库操作。它通过调用 ParameterHandler 来设置 SQL 参数,并通过调用 ResultSetHandler 来处理查询结果。



实现思路:


1 首先我们需要对数据的结果集进行拦截,也就是说需要拦截这个接口的方法

2 得到数据返回的结果集后,对结果集转换成 List 进行遍历脱敏

3 脱敏的时候我们还需要判断一下哪些字段需要进行脱敏,这里我们定义注解来标识需要脱敏的字段(在这个注解里面可以定义一些脱敏策略,比如对手机号的脱敏规则、身份证的脱敏规则等等)

4 遍历的时候通过反射,获取所有属性

5 我这里的脱敏有三个条件

        a、必须带有 脱敏标识注解
        b、必须是 String 类型
        c、不得为空,这里直接使用工具类来判断 StringUtils.isEmpty()


6 脱敏条件达成后,就获取该注解上的 脱敏策略,根据脱敏策略 对属性进行脱敏

7 将脱敏后的结果重新设置到属性上


具体实现步骤


定义注解和不同的脱敏策略

import java.util.function.Function;//这里的Function是jdk8新特性,自己了解一哈子
//提示:传入一个函数执行
public interface Desensitizer extends Function<String,String> {}
//这里定义脱敏策略
public enum TuoMinStrategy {/*手机号*/PHONE(s->s.replaceAll("^(\\\\d{3})\\\\d{4}(\\\\d{4})$","$1****$2")),/*用户名 匹配中文全部替换*/USERNAME(s->s.replaceAll("[\\u4e00-\\u9fa5]","*"));private final Desensitizer desensitizer;TuoMinStrategy(Desensitizer d) {desensitizer = d;}public Desensitizer getDesensitizer() {return desensitizer;}
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;//作用于属性上
@Target(ElementType.FIELD)
//运行时生效
@Retention(RetentionPolicy.RUNTIME)
public @interface TuoMin {/*** 脱敏策略* @return*/TuoMinStrategy strategy();}

脱敏插件核心类
注意:注解中的属性,method和args不是硬背的,有技巧,如这个,
ResultSetHandler类,点进去,要拦截哪个方法,方法名直接复制,方法里的参数,直接copy 引用

import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.sql.Statement;
import java.util.List;
import java.util.stream.Stream;@Component //需要放入到 ioc 容器中拦截器才会生效哦
//指定要拦截的目标方法的注解
//<h1>1、这个就是指定需要拦截的方法,这里我们指定拦截返回结果集的方法</h1>
@Intercepts(@Signature(type = ResultSetHandler.class,method = "handleResultSets",args= Statement.class))
public class TongMinPlugin implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {//<h1>2、得到数据返回的结果集,对结果集转换成 List<Object> 进行遍历脱敏</h1>List<Object> records = (List<Object>) invocation.proceed();System.out.println("records = " + records);// 遍历数据 调用 tuoMin 这个方法records.forEach(this::tuoMin);return records;}private void tuoMin(Object source) {Class<?> sourceClass = source.getClass();System.out.println("sourceClass = " + sourceClass);MetaObject metaObject = SystemMetaObject.forObject(source);//这个东东是 mybatis 提供的,通过这个玩意我们可以得到属性的值System.out.println("metaObject = " + metaObject);// 使用 stream 流/*** 1、得到所有属性* 2、筛选出带有 TuoMin.class 注解的属性* 3、调用doTuoMin方法将这些属性脱敏*/Stream.of(sourceClass.getDeclaredFields()).filter(field -> field.isAnnotationPresent(TuoMin.class)).forEach(field->doTuoMin(metaObject,field));}private void doTuoMin(MetaObject metaObject, Field field) {System.out.println("metaObject = " + metaObject);System.out.println("field = " + field);String name = field.getName();System.out.println("name = " + name);Object value = metaObject.getValue(name);//根据属性名得到属性值System.out.println("value = " + value);// 脱敏条件:必须为String类型,值不等于空if (String.class == metaObject.getGetterType(name) && StringUtils.hasText(value.toString())) {//获取脱敏策略TuoMin tuoMin = field.getAnnotation(TuoMin.class);System.out.println("tuoMin = " + tuoMin);TuoMinStrategy type = tuoMin.strategy();System.out.println("type = " + type);// 调用策略正则表达式脱敏,得到结果Object apply = type.getDesensitizer().apply((String) value);System.out.println("apply = " + apply);// 将脱敏后的结果重新设置到属性上metaObject.setValue(name,apply);}}}

3 在需要脱敏的pojo的字段上加上注解,如

@TableField(value = "title")
@TuoMin(strategy = TuoMinStrategy.USERNAME) //加上注解并指定脱敏策略
private String title;

测试,举例

脱敏前:
张三达美脱敏后:
张 * * 美


部分文字和代码引用博文
【MyBatis】脱敏插件_前端脱敏插件是什么-CSDN博客

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

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

相关文章

python基础语法 004-3流程控制- while

1 while while 主要用的场景没有 for 循环多。 while循环&#xff1a;主要运行场景 我不知道什么时候结束。。。不知道运行多少次 1.1 基本用法 # while 4 > 3: #一直执行 # print("hell0")while 4 < 3: #不会打印&#xff0c;什么都没有print("…

IT之旅启航:高考后IT专业预习全攻略

✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您的点赞、关注、收藏、评论&#xff0c;是对我最大…

Java知识点大纲

文章目录 第一阶段&#xff1a;JavaSE1、面向对象编程(基础)1)面向过程和面向对象区别2)类和对象的概述3)类的属性和方法4)创建对象内存分析5)构造方法(Construtor)及其重载6)对象类型的参数传递7)this关键字详解8)static关键字详解9)局部代码块、构造代码块和静态代码块10)pac…

2-24 基于图像处理的细胞计数方法

基于图像处理的细胞计数方法。经过初次二值化、中值滤波后二值化、优化后二值化图像、填充背景色的二进制图像、开运算后的图像一系列运算后&#xff0c;进行标签设置&#xff0c;最终得到细胞总数。程序已调通&#xff0c;可直接运行。 2-24 细胞计数方法 中值滤波后二值化 - …

【C++】 解决 C++ 语言报错:Invalid Cast

文章目录 引言 无效类型转换&#xff08;Invalid Cast&#xff09;是 C 编程中常见且严重的错误之一。当程序试图进行不合法或不安全的类型转换时&#xff0c;就会发生无效类型转换错误。这种错误不仅会导致程序崩溃&#xff0c;还可能引发不可预测的行为。本文将深入探讨无效…

图像增强方法汇总OpenCV+python实现【第一部分:常用图像增强方法】

图像增强方法汇总OpenCVpython实现【第一部分】 前言常用的图像增强方法1. 旋转&#xff08;Rotation&#xff09;&#xff1a;2. 平移&#xff08;Translation&#xff09;&#xff1a;3. 缩放&#xff08;Scaling&#xff09;&#xff1a;4. 剪切变换&#xff08;Shear Trans…

UserWarning: IPython History requires SQLite, your history will not be saved

UserWarning: IPython History requires SQLite, your history will not be saved 很久未打开pycharm&#xff0c;控制台出现爆红 解决方法&#xff1a; 重启pycharm&#xff0c;就好啦&#xff01;&#xff01;&#xff01;我猜测可能是上次pycharm没有关闭就电脑关机&…

《企业实战分享 · 内存溢出分析》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; 近期刚转战 CSDN&#xff0c;会严格把控文章质量&#xff0c;绝不滥竽充数&#xff0c;如需交流&#xff…

用PyQt5打造炫酷界面:深入解析pyqt5-custom-widgets

在PyQt5中&#xff0c;使用自定义小部件可以为应用程序增添更多实用性和时尚感。pyqt5-custom-widgets是一个开源项目&#xff0c;提供了一系列有用且时尚的自定义小部件&#xff0c;如开关按钮、动画按钮等。本文将详细介绍pyqt5-custom-widgets的安装和使用方法。 安装 可以…

权限维持Linux---监控功能Strace后门命令自定义Alias后门

免责声明:本文仅做技术交流与学习... 目录 监控功能Strace后门 1、记录 sshd 明文 监控 筛选查看 2、记录sshd私钥 命令自定义Alias后门 1、简单粗鲁实现反弹&#xff1a; 靶机替换命令 攻击机监听上线 2.升级(让命令正常) 将反弹命令进行base64编码 替换alias命令 …

【Linux】--help,man page , info page

我们知道Linux有很多的命令&#xff0c;那LInux要不要背命令&#xff1f; 答案是背最常用的那些就行了 那有的时候我们想查询一些命令的详细用法该怎么办呢&#xff1f; 这里我给出3种方法 1.--help --help的使用方法很简单啊 要查询的命令 --help 我们看个例子 这里我只…

java版企业工程管理系统源码:全方位的项目管理解决方案

工程管理系统是一款专注于建设工程项目全生命周期管理的软件。它覆盖了项目从策划、设计、施工到竣工的每一个阶段&#xff0c;提供全方位的管理功能。系统采用模块化设计&#xff0c;包括系统管理、系统设置、项目管理、合同管理、预警管理、竣工管理、质量管理、统计报表和工…

6月30日功能测试Day10

3.4.4拼团购测试点 功能位置&#xff1a;营销-----拼团购 后台优惠促销列表管理可以添加拼团&#xff0c;查看拼团活动&#xff0c;启动活动&#xff0c;编辑活动&#xff0c;删除活动。 可以查看拼团活动中已下单的订单以状态 需求分析 功能和添加拼团 商品拼团活动页 3…

python使用pywebview集成vue3和element-plus开发桌面系统框架

随着web技术越来越成熟&#xff0c;就连QQ的windows客户端都用web技术来开发&#xff0c;所以在未来&#xff0c;web技术来开发windows桌面软件也会越来越多&#xff0c;所以在此发展驱动之下&#xff0c;将最近流程的python与web技术相结合&#xff0c;使用vue3和element-plus…

图像增强 目标检测 仿射变换 图像处理 扭曲图像

1.背景 在目标检测中&#xff0c;需要进行图像增强。这里的代码模拟了旋转、扭曲图像的功能&#xff0c;并且在扭曲的时候&#xff0c;能够同时把标注的结果也进行扭曲。 这里忽略了读取xml的过程&#xff0c;假设图像IMG存在对应的标注框&#xff0c;且坐标为左上、右下两个…

[C++初阶]vector的初步理解

一、标准库中的vector类 1.vector的介绍 1. vector是表示可变大小数组的序列容器 &#xff0c; 和数组一样&#xff0c;vector可采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问&#xff0c;和数组一样高效。但是又不像数组&#xff0c;它的大…

Java学习高级一

修饰符 static 类变量的应用场景 成员方法的分类 成员变量的执行原理 成员方法的执行原理 Java之 main 方法 类方法的常见应用场景 代码块 设计模式 单例设计模式 饿汉式单例设计模式 懒汉式单例设计模式 继承 权限修饰符

小红书 达芬奇:生活问答 AI 机器人

小红书去年 9 月开始内测的生活问答 AI 机器人&#xff1a;达芬奇&#xff0c;现在可以在小红书 APP 上用了 得益于小红书平台的特性&#xff0c;该助手擅长吃、住、宠、喝、学等等各类生活知识&#xff0c;目前还在搞活动&#xff0c;写评测笔记最高得 666 元

为什么不能在foreach中删除元素

文章目录 快速失败机制&#xff08;fail-fast&#xff09;for-each删除元素为什么报错原因分析逻辑分析 如何正确的删除元素remove 后 breakfor 循环使用 Iterator 总结 快速失败机制&#xff08;fail-fast&#xff09; In systems design, a fail-fast system is one which i…

网络基础:EIGRP

EIGRP&#xff08;Enhanced Interior Gateway Routing Protocol&#xff09;是由思科开发的一种高级距离矢量路由协议&#xff0c;结合了距离矢量和链路状态路由协议的优点&#xff1b;EIGRP具有快速收敛、高效带宽利用、负载均衡等特点&#xff0c;适用于各种规模的网络。EIGR…