MybatisPlus优雅实现加密?

前言

最近在搞个安全需求,需要对敏感字段做加密存储。于是,,于是我就躺了个坑。

方案梳理

方案一:基于Mybatis的拦截器Interceptor

我的第一个反应其实是基于Mybatis的拦截器Interceptor机制实现,在设置参数的时候对参数进行拦截并加密,而在查询的时候对返回值进行解密。当然,不管是那种方案都需要对敏感字段进行标记。
实现可参考mybatis-plus实现数据字段加解密

PS: 该博客可以满足绝大部分场景了,但Map、List<String>没有考虑。不过这也是基于Interceptor的弊端,就是你需要考虑更多的细节。

方案二:基于Mybatis的TypeHandler

Mybatis支持针对特定字段的类型进行特殊处理,这为字段的加解密提供了可能。关于Mybatis的TypeHandler,大家可以看看官方的【类型处理器(typeHandlers)】
简单来说就一句话:在执行SQL之前对入参和返回值进行处理

而Mybatis本身通过这个进行类型转换。想知道其自带了多少TypeHandler可以看看mybatis的这个包:org.apache.ibatis.type

基于这个特点,我们就可以利用来实现字段的加解密功能。为了不影响那些不需要加解密的字段,我们就必须要在在特定的字段上进行指定。

对于select,可以通<resultMap>标签来指定,例如:

<resultMap type="org.apache.ibatis.submitted.rounding.User" id="usermap2"><result column="roundingMode" property="roundingMode" typeHandler="org.apache.ibatis.type.EnumTypeHandler"/>
</resultMap>

对于入参,则不需要区分是什么语句,只需要在取值的时候指定就行:

<insert id="insert2"> insert into users2 (id, name, funkyNumber, roundingMode) values(#{id}, #{name}, #{funkyNumber}, #{roundingMode, typeHandler= org.apache.ibatis.type.EnumTypeHandler})
</insert>

这便是我们基于Mybatis实现加解密的理论基础。

MybatisPlus优雅实现加解密

众所周知,MybatisPlus并不准备取代Mybatis,而是对Mybatis的增强,增加一些便于使用的特性。
以TypeHandler为例:

@TableName(value = "foo_user", autoResultMap = true)
public class User {private String username;/*** 通过mp的@TableField注解指定TypeHandler。* PS: 这里的MyTypeHandler,是需要自己实现TypeHandler接口的哈。* 由于我这里没有逻辑,就不给大伙看了*/@TableField(typeHandler = MyTypeHandler.class)private String mobile;
}public interface UserMapper extends BaseMapper<User> {
}

就这样,我们就完成了MybatisPlus(官方源码缩写为mp)的配置。我们可以很方便的调用UserMapper#insert方法,通过上面指定的typeHandler来执行我们需要对mobile字段的加密逻辑。
调用UserMapper#selectById方法,也会自动的执行typeHandler的解密逻辑。后者,通过@TableName的autoResultMap = true配置生效,他会自动向Mybatis中注入一个ResultMap,其效果等同于我们在xml文件中书写的resultMap。

感兴趣的同学,可以参考这篇文章:
基于MybatisPlus的实现

MybatisPlus真的这么优雅丝滑?

事情并没有这么简单!前面我们大致了解了Mybatis本身提供的TypeHandler组件,也知道MybatisPlus的基于TypeHandler为我们提供的简单易用的优雅的使用方式。可是,各位同学想过没有,我们自己在xml中写的SQL呢?MybatisPlus也能如此智能、方便地达到我们的目的呢???
很显然,不能够。我们在xml中写update语句,没有指定typeHandler的话,是MybatisPlus也是无能为力的。这是因为他不能掌握我们的SQL了,更不能为我们添加指定typeHandler。这对于select语句也是如此!
事实上,MybatisPlus在其注解之上也有说明:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface TableField {/*** JDBC类型 (该默认值不代表会按照该值生效),* 只生效于 mp 自动注入的 method,* 建议配合 {@link TableName#autoResultMap()} 一起使用* <p>* {@link ResultMapping#jdbcType} and {@link ParameterMapping#jdbcType}** @since 3.1.2*/JdbcType jdbcType() default JdbcType.UNDEFINED;/*** 类型处理器 (该默认值不代表会按照该值生效),* 只生效于 mp 自动注入的 method,* 建议配合 {@link TableName#autoResultMap()} 一起使用* <p>* {@link ResultMapping#typeHandler} and {@link ParameterMapping#typeHandler}** @since 3.1.2*/Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface TableName {/*** 是否自动构建 resultMap 并使用,* 只生效于 mp 自动注入的 method,* 如果设置 resultMap 则不会进行 resultMap 的自动构建并注入,* 只适合个别字段 设置了 typeHandler 或 jdbcType 的情况** @since 3.1.2*/boolean autoResultMap() default false;
}

清楚明白地写着只支持自动生成的方法。

要命的是,我们在实际项目中,不可能只使用单表查询,这样一来,我们就不得不自己写SQL。然而,当你使用MybatisPlus这么方便愉快地写代码的时候,你还会深入源码看注释吗?还会深入源码了解其实现原理吗?不,你不会,本来就是因为懒才使用MybatisPlus的。这就使得很多同学陷入迷茫,排查问题不知所措:为什么就是不生效,为什么这个方法可以?想想都崩溃!

总结

  1. MybatisPlus的@TableField注解的部分字段只使用于自动生成的方法,因为它可以掌控和改造目标SQL的生成。本质上还是在使用Mybatis的功能。例如:指定typeHandler、javaType。
  2. Mybatis本身提供了TypeHandler组件,我们可以基于这个来实现敏感字段的加解密。

后记

给大家个建议,如果你想偷懒,而且你的项目足够简单,简单到通过单表操作就能够解决问题,那么可以使用MybatisPlus。否则,我不建议大家使用MybatisPlus,尤其不建议使用这种半吊子的功能。实际上,MybatisPlus主要还是希望基于Mybatis给大家提供一些好用的特性。但是,随着我使用地越多,就越不想使用它。上一个躺坑的是,我需要通过mockito来mock这些Mapper,来做单元测试。简直麻了,因为它自动生成的方法太灵活了,尤其是链式方法。

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

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

相关文章

Vue开发实例(十三)用户登录功能

使用Vue实现登录具有以下几个好处&#xff1a; 响应式界面&#xff1a;Vue框架的响应式特性可以帮助开发者轻松地实现用户登录界面的交互效果&#xff0c;包括表单验证、实时错误提示等&#xff0c;从而提升用户体验。组件化开发&#xff1a;Vue框架支持组件化开发&#xff0c;…

【AI学习】卷积神经网络的由来

乱读书&#xff0c;看见这么这段话&#xff1a; “生物的眼睛以精巧的方式与大脑相连。视网膜上的感光细胞&#xff08;人眼的视杆或视锥&#xff09;并不直接连接到单个神经元上&#xff0c;而是会有一整片区域的神经元与每一个感光细胞相连接。相邻的神经元会连接到视网膜上相…

最新版npm详解

如&#xff1a;npm中搜索 jQuery image.png image.png 接地气的描述&#xff1a;npm 类似于如下各大手机应用市场 image.png image.png 查看本地 node 和 npm 是否安装成功 image.png image.png 或 npm install -g npm image.png image.png image.png image.png image.…

【数据库】MySQL

文章目录 概述DDL数据库操作查询使用创建删除 表操作创建约束MySqL数据类型数值类型字符串类型日期类型 查询修改删除 DMLinsertupdatedelete DQL基本查询条件查询分组查询分组查询排序查询分页查询 多表设计一对多一对一多对多设计步骤 多表查询概述内连接外连接 子查询标量子…

这所211专硕22408复试线310分,学硕收调剂!辽宁大学计算机考研考情分析!

辽宁大学信息学院下设计算机科学与技术、电子信息科学与技术、通信工程、信息管理与信息系统、软件工程5个本科专业&#xff0c;有计算机软件与理论、计算机应用技术2个硕士学位授权点&#xff0c;软件工程和计算机技术两个专业硕士学位点&#xff0c;1个计算机应用研究所、1个…

wordpress woocommer 添加代码实现,点击按钮,将产品添加到购物车并且跳转到结账页面

wordpress woocommer 添加代码实现&#xff0c;点击按钮&#xff0c;将产品添加到购物车并且跳转到结账页面 案列代码1&#xff0c;解决的是普通产品的 //短代码生成按钮&#xff0c;传入短代码&#xff0c;点击直接到达结账页面 function add_product_to_cart_button($atts)…

案例题(第一版)

案例题目 软件架构设计考点&#xff08;历年必考&#xff09; 软件架构设计通常在每年的第一题&#xff0c;该题必考 必备概念 必备概念即考试必须要默写出来的概念 概念描述软件架构风格是指描述特定软件系统组织方式和惯用模式。组织方式描述了系统的组成构件和这些构件的组…

在Spring Boot项目中通过自定义注解实现多数据源以及主备数据库切换

在现代的企业应用开发中&#xff0c;使用多数据源是一个常见的需求。尤其在关键应用中&#xff0c;设置主备数据库可以提高系统的可靠性和可用性。在这篇博客中&#xff0c;我将展示如何在Spring Boot项目中通过自定义注解实现多数据源以及主备数据库切换。 在此说明&#xff…

【HTML】制作一个跟随鼠标的流畅线条引导页界面(可直接复制源码)

目录 前言 HTML部分 CSS部分 JS部分 效果图 总结 前言 无需多言&#xff0c;本文将详细介绍一段HTML代码&#xff0c;图中线条可跟随鼠标移动&#xff0c;具体内容如下&#xff1a; 开始 首先新建一个HTML的文本&#xff0c;文本名改为[index.html]&#xff0c;创建好后右…

【逻辑漏洞】验证码绕过

【逻辑漏洞】验证码绕过 参数操纵值提取和重用自动化和识别其他测试 参数操纵 随机应变的请求方法&#xff1a;清空发送验证码参数。尝试更改HTTP方法从POST到GET或其他动词&#xff0c;并更改数据格式&#xff0c;例如在表单数据和JSON之间切换。发送空验证码&#xff1a;提交…

第十一节 SpringBoot Starter 面试题

一、面试题 很多同学的简历都写着熟悉 SpringBoot&#xff0c; 而 Starter 的实现原理被当作的考题的的情况越来越多。 来源牛客网关于 starter 的一些面试题 情景一、路虎一面 情景二、蔚来 情景三、同花顺 Starter 频频出现&#xff0c;因此在面试准备时&#xff0c;这道题…

mdm 推送证书制作教程

第一步点击获取&#xff0c;点击以后会下载一个zip压缩包 解压以后&#xff1a;会得到四个文件&#xff0c;请务必保存好&#xff0c;待会需要使用 登录apple开发者官网 https://developer.apple.com/account/resources/certificates/list 点击添加证书 找到mdm csr 然后点击…

赶紧收藏!2024 年最常见 20道 Redis面试题(六)

上一篇地址&#xff1a;赶紧收藏&#xff01;2024 年最常见 20道 Redis面试题&#xff08;五&#xff09;-CSDN博客 十一、Redis集群之间是如何复制的&#xff1f; Redis 集群是一个分布式系统&#xff0c;它由多个节点组成&#xff0c;这些节点共同存储数据并提供服务。在 R…

C++小游戏 合集

生化危机 #include<conio.h> #include<string.h> #include<stdio.h> #include<stdlib.h> #include<windows.h> #include<time.h> #include<direct.h> int n,round,gold0; bool f1,f2,f3,deadfalse,PC_64Bit; char str[4]; struct n…

用Python代码批量提取PDF文件中的表格

PDF文档中常常包含大量数据&#xff0c;尤其是官方报告、学术论文、财务报表等文档&#xff0c;往往包含了结构化的表格数据。表格作为承载关键信息的载体&#xff0c;其内容的准确提取对于数据分析、研究论证乃至业务决策具有重大意义。然而&#xff0c;PDF格式虽保证了文档的…

Vue从入门到实战Day12

一、Pinia快速入门 1. 什么是Pinia Pinia是Vue的最新状态管理工具&#xff0c;是Vuex的替代品 1. 提供更加简单的API&#xff08;去掉了mutation&#xff09; 2. 提供符合组合式风格的API&#xff08;和Vue3新语法统一&#xff09; 3. 去掉了modules的概念&#xff0c;每一…

C++|设计模式(二)|简单工厂和工厂方法模式

本文探讨两种广泛使用的创建型模式——简单工厂模式和工厂方法模式&#xff0c;解释他们的实现细节、优势以及应用场景。 在下一篇文章中&#xff0c;我会补充抽象工厂模式&#xff0c;其实工厂模式主要就是为了封装对象的创建过程&#xff0c;如果我们不进行封装&#xff0c;…

人工智能应用-实验7-胶囊网络分类minst手写数据集

文章目录 &#x1f9e1;&#x1f9e1;实验内容&#x1f9e1;&#x1f9e1;&#x1f9e1;&#x1f9e1;代码&#x1f9e1;&#x1f9e1;&#x1f9e1;&#x1f9e1;分析结果&#x1f9e1;&#x1f9e1;&#x1f9e1;&#x1f9e1;实验总结&#x1f9e1;&#x1f9e1; &#x1f9…

Python TCP编程简单实例

客户端&#xff1a;创建TCP链接时&#xff0c;主动发起连接的叫做客户端 服务端&#xff1a;接收客户端的连接 连接其他服务器 可以通过tcp连接其他服务器。 示例&#xff1a; import socket# 1.创建一个socket # 参数1&#xff1a;指定协议 AF_INET&#xff08;ipv4&#…