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

MyBatis 插件

🎯 一、MyBatis 插件的本质:不是“插件”,而是“拦截器”!

很多开发者说“MyBatis 插件”,其实更准确的叫法是 Interceptor(拦截器)
它不是像浏览器插件那样“附加功能”,而是 MyBatis 框架提供的一种 面向切面编程(AOP)能力,让你在 SQL 执行的关键节点上插入自定义逻辑

一句话概括原理
MyBatis 插件 = 基于 JDK 动态代理 + 责任链模式,对四大核心接口的方法进行精准拦截。


🔍 二、底层原理深度剖析(展现技术深度)

MyBatis 允许你拦截以下 四大核心接口 的方法:

接口作用可拦截场景
ExecutorSQL 执行入口审计、缓存、分页、超时控制
StatementHandler处理 PreparedStatementSQL 改写(如多租户、分表)、SQL 注入防护
ParameterHandler设置 SQL 参数参数加密、脱敏、校验
ResultSetHandler处理查询结果字段脱敏、自动转换、敏感数据过滤

🧠 工作机制三步走:

  1. 声明拦截点:通过 @Intercepts({ @Signature(...) }) 注解指定要拦截的类、方法、参数。
  2. 代理包装:MyBatis 在创建上述接口实例时,调用 Plugin.wrap(target, interceptor),生成 JDK 动态代理对象。
  3. 执行拦截:当目标方法被调用时,先进入 intercept(Invocation invocation),你可以在 invocation.proceed() 前后做增强。

💡 关键洞察:
插件只对“接口”生效(因为用的是 JDK 代理),且 多个插件会形成嵌套代理链,顺序由注册先后决定。

🌟 三、为什么 MyBatis 插件值得在架构中使用?(价值升华)

它解决了传统开发中的三大痛点:

痛点插件方案优势
业务代码被横切逻辑污染将审计、日志、权限等抽离到插件关注点分离,代码更干净
修改 SQL 需要动所有 Mapper在插件中统一重写 SQL零侵入,一处修改,全局生效
无法监控底层 JDBC 行为直接拦截 Statement/ResultSet比 Spring AOP 更底层、更精准

✅ 这就是为什么:高级工程师用插件,初级工程师改业务代码。

🚀 四、实战案例:Spring Boot + MyBatis 实现 SQL 审计插件

现在,我们来看一个 真实、可落地、有业务价值 的例子——SQL 审计插件,这在金融、政务、医疗等强监管行业是刚需!

📌 需求背景

  • 记录所有 DML 操作(INSERT/UPDATE/DELETE)
  • 包含:SQL 语句、实际参数、操作人、IP、执行时间、影响表名
  • 敏感字段(如密码、手机号)自动脱敏
  • 异步写入日志,不影响主事务性能

🛠️ 代码实现(Spring Boot 3 + MyBatis)

步骤 1:定义插件类
@Component
@Intercepts(@Signature(type = Executor.class,method = "update",args = {MappedStatement.class, Object.class}
))
public class SqlAuditInterceptor implements Interceptor {@Autowiredprivate AuditLogService auditLogService;@Overridepublic Object intercept(Invocation invocation) throws Throwable {MappedStatement ms = (MappedStatement) invocation.getArgs()[0];SqlCommandType cmdType = ms.getSqlCommandType();// 只审计 DMLif (!isDml(cmdType)) return invocation.proceed();BoundSql boundSql = ms.getBoundSql(invocation.getArgs()[1]);String sql = boundSql.getSql();String table = extractTableName(sql);String params = maskSensitive(boundSql.getParameterObject());long start = System.currentTimeMillis();try {Object result = invocation.proceed(); // 执行原 SQLlong cost = System.currentTimeMillis() - start;// 构建审计日志AuditLog log = new AuditLog().setSql(sql).setParams(params).setTable(table).setOperator(getCurrentUsername()).setClientIp(getClientIp()).setCostMs(cost).setCommandType(cmdType.name());auditLogService.asyncSave(log); // 异步保存return result;} catch (Exception e) {log.error("审计异常", e);throw e;}}// ... 工具方法:脱敏、取用户、取 IP、解析表名等
}
步骤 2:注册插件(Spring Boot 配置)
@Configuration
@MapperScan("com.company.mapper")
public class MyBatisConfig {@Beanpublic ConfigurationCustomizer mybatisCustomizer(SqlAuditInterceptor interceptor) {return config -> config.addInterceptor(interceptor);}
}
步骤 3:异步日志服务(避免阻塞)
@Service
public class AuditLogService {private static final Logger AUDIT = LoggerFactory.getLogger("AUDIT");@Asyncpublic void asyncSave(AuditLog log) {AUDIT.info("AUDIT | user={} | ip={} | table={} | sql=[{}] | params=[{}]",log.getOperator(), log.getClientIp(), log.getTable(),log.getSql(), log.getParams());}
}

📊 审计日志效果示例

AUDIT | user=admin | ip=10.0.0.5 | table=user 
| sql=[UPDATE user SET phone=? WHERE id=?] 
| params=[{phone=138****1234, id=1001}]

✅ 敏感字段自动脱敏
✅ 操作人/IP 自动采集
✅ 零侵入业务代码
✅ 异步写入,性能无损

💎 五、总结

“MyBatis 插件不是炫技,而是 工程化思维的体现
它让我们在不修改一行业务代码的前提下,实现 系统级能力的统一管控

真正的架构能力,不在于用了多少框架,而在于能否用最克制的方式,解决最本质的问题。

http://www.dtcms.com/a/592995.html

相关文章:

  • 甘肃省城乡住房建设厅网站首页微商软件自助商城
  • 一文掌握,kanass安装与配置
  • C# ASP.NET MVC 数据验证实战:View 层双保险(Html.ValidationMessageFor + jQuery Validate)
  • 工信部 网站 邮箱内容管理系统做网站
  • arcgis用累计值进行分级
  • 生理学实验系统 生理学实验系统软件 集成化生物信号采集与处理系统生物信号采集处理系统 生理机能实验处理系统
  • 环境变量与程序地址空间
  • Node.js的主要应用场景和简单例子
  • 做视频解析网站是犯法的么360优化大师
  • 大网站cn域名淘宝店铺装修模板免费下载
  • VBA即用型代码手册:利用函数保存为PDF文件UseFunctionSaveAsPDF
  • JPA 的说明和使用
  • MyBatis使用LocalDateTime会报错
  • web网页开发,在线财务管理系统,基于Idea,html,css,jQuery,java,ssm,mysql。
  • 2025汉化idea创建JSP项目
  • 如何高效处理日常 PDF 文档?
  • LeetCode 2342.数位和相等数对的最大和
  • 企业网站建设需了解什么软文投放平台有哪些?
  • pink老师html5+css3day07
  • 各个手机芯片型号
  • [Qt学习笔记]Qt5.15.2版本安装及调整组件
  • C语言--文件读写函数的使用,对文件读写知识有了更深的了解。
  • WEBweb前端OPPO手机商城网站项目
  • 虚拟技术 云手机是指什么?
  • 传播易网站开发方案饿了么网站做生鲜吗
  • 制作网站的网站fullpage网站怎么做
  • 【element-plus】element-plus升级到v2.11.7,el-tree文字不显示问题
  • 服务器接收用户注册信息教程
  • 【Linux系统编程】进程概念(四)进程优先级、进程切换、环境变量和程序地址空间
  • 数据结构(18)