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

Mybatis-Plus 插件机制与自定义插件实现

1. Mybatis-Plus 插件系统概述

Mybatis-Plus 提供了一个简单而强大的插件机制,允许开发者在 MyBatis 执行 SQL 的过程中插入自定义逻辑。通过插件机制,用户可以实现对 SQL 执行过程的拦截和修改。Mybatis-Plus 插件基于 MyBatis 的拦截器模式进行实现,能够在 MyBatis 执行 SQL 语句前、后进行自定义操作。

插件机制的核心是 Interceptor 接口,开发者可以通过实现该接口,自定义拦截 SQL 执行的行为。Mybatis-Plus 内置了多个常用插件,例如分页插件、性能分析插件等。插件的配置和使用非常简单,能够提升开发效率,减少重复性代码。

2. 常见插件:分页插件,性能分析插件
  • 分页插件

    分页插件是 Mybatis-Plus 中最常用的插件之一,它通过拦截 SQL 查询语句,自动为查询添加分页条件。只需在配置中启用分页插件,并在查询时传入分页参数,就能够快速实现分页查询。

    配置分页插件的代码如下:

    @Configuration
    public class MybatisPlusConfig {@Beanpublic PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();}
    }
    

    在查询时,使用 Page 对象作为分页参数:

    Page<User> page = new Page<>(1, 10);  // 第1页,每页10条
    IPage<User> userPage = userMapper.selectPage(page, null);
    
  • 性能分析插件

    性能分析插件用于输出 SQL 执行的性能日志。通过该插件,可以记录每个 SQL 的执行时间,并警告执行时间超过设定阈值的 SQL 语句。它的配置方式如下:

    @Configuration
    public class MybatisPlusConfig {@Beanpublic PerformanceInterceptor performanceInterceptor() {PerformanceInterceptor interceptor = new PerformanceInterceptor();interceptor.setMaxTime(1000); // 设置最大执行时间,超过则警告interceptor.setFormat(true);  // SQL 格式化输出return interceptor;}
    }
    
3. 如何实现自定义插件

要实现自定义插件,首先需要实现 MyBatis 的 Interceptor 接口,该接口包含一个 intercept 方法,用于定义拦截逻辑。在 intercept 方法中,可以通过 Invocation 对象来获取当前的 SQL 语句,并进行自定义操作。

以下是一个自定义插件的实现示例:

public class MyCustomPlugin implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {// 获取执行的 SQL 语句MappedStatement ms = (MappedStatement) invocation.getArgs()[0];BoundSql boundSql = ms.getBoundSql(invocation.getArgs()[1]);// 在此处修改 SQL,例如增加特定的查询条件String sql = boundSql.getSql();String modifiedSql = sql + " WHERE is_active = 1"; // 假设为筛选活跃用户// 设置修改后的 SQLField field = BoundSql.class.getDeclaredField("sql");field.setAccessible(true);field.set(boundSql, modifiedSql);return invocation.proceed();}@Overridepublic Object plugin(Object target) {// 通过 MyBatis 的插件机制包装目标对象if (target instanceof StatementHandler) {return Plugin.wrap(target, this);}return target;}@Overridepublic void setProperties(Properties properties) {// 可以根据需要在此配置插件的属性}
}

然后,需要将自定义插件配置到 MyBatis 中:

@Configuration
public class MybatisPlusConfig {@Beanpublic MyCustomPlugin myCustomPlugin() {return new MyCustomPlugin();}
}
4. 插件的开发与使用场景
  • 插件开发

    插件的开发通常基于以下几个步骤:

    1. 实现 Interceptor 接口,重写 interceptpluginsetProperties 方法。
    2. intercept 方法中编写 SQL 拦截逻辑,修改或记录 SQL 执行信息。
    3. 使用 Plugin.wrap 方法将插件与目标对象进行绑定,以便 MyBatis 能够正确调用插件。
    4. 配置插件,将其注册到 MyBatis 的插件列表中。
  • 插件的使用场景

    • 动态 SQL 扩展:可以利用插件动态地添加查询条件,例如自动增加租户字段、权限过滤等。
    • SQL 性能监控:通过性能分析插件可以检测 SQL 执行的性能,帮助开发者优化查询。
    • 审计日志:通过插件记录每次 SQL 执行的信息,可以实现数据库的审计功能。
    • 数据加密解密:在插件中进行数据加密解密处理,保证数据的安全性。
5. SaaS 系统的应用场景:租户数据隔离插件

在 SaaS 系统中,通常会有多个租户(客户),而每个租户的数据必须进行隔离,避免数据泄漏或混合。这时,Mybatis-Plus 插件机制可以发挥重要作用,通过自定义插件来自动为每个 SQL 查询添加租户隔离条件。

假设系统中的每个租户都有一个唯一的 tenant_id,我们可以通过自定义插件,在所有的查询中自动添加租户 ID 条件,从而实现数据的隔离。以下是一个租户数据隔离插件的示例:

public class TenantDataIsolationPlugin implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {// 获取执行的 SQL 语句MappedStatement ms = (MappedStatement) invocation.getArgs()[0];BoundSql boundSql = ms.getBoundSql(invocation.getArgs()[1]);// 获取当前租户的 tenant_id,假设通过 ThreadLocal 存储String tenantId = TenantContext.getTenantId();// 为每个 SQL 增加租户字段条件String sql = boundSql.getSql();// 如果查询的表没有 tenant_id 字段,不需要添加租户过滤条件if (!isTenantIdRequired(ms)) {return invocation.proceed(); // 跳过插件处理,直接执行查询}String modifiedSql = sql + " AND tenant_id = '" + tenantId + "'"; // 设置修改后的 SQLField field = BoundSql.class.getDeclaredField("sql");field.setAccessible(true);field.set(boundSql, modifiedSql);return invocation.proceed();}@Overridepublic Object plugin(Object target) {// 通过 MyBatis 的插件机制包装目标对象if (target instanceof StatementHandler) {return Plugin.wrap(target, this);}return target;}@Overridepublic void setProperties(Properties properties) {// 可以根据需要在此配置插件的属性}/*** 判断当前查询的表是否需要租户隔离。* 例如,如果表中没有 tenant_id 字段,则不需要隔离。*/private boolean isTenantIdRequired(MappedStatement ms) {String tableName = ms.getSqlCommandType().name();// 假设查询表的名字中包含 "no_tenant" 时,表示不需要隔离return !tableName.contains("no_tenant");}
}

在这个插件中,我们假设每次操作的 tenant_id 是通过 TenantContext.getTenantId() 方法获取的(可以利用 ThreadLocal 存储每个线程的租户 ID)。插件会在每个 SQL 查询中自动加上租户条件 AND tenant_id = '当前租户ID',但如果查询的表没有 tenant_id 字段,或者表名包含 no_tenant(例如某些不需要数据隔离的表),插件将跳过租户隔离的处理,直接执行查询。

配置插件:

@Configuration
public class MybatisPlusConfig {@Beanpublic TenantDataIsolationPlugin tenantDataIsolationPlugin() {return new TenantDataIsolationPlugin();}
}

应用场景

  • 在 SaaS 系统中,每个租户的数据会存储在相同的数据库表中。通过该插件,开发者无需手动在每个查询中添加租户 ID 条件,系统自动为每个 SQL 查询注入当前租户的 ID,从而实现数据隔离。
  • 对于一些不需要租户隔离的表(如系统表、公共配置表等),通过 isTenantIdRequired 方法判断,避免不必要的条件添加。
  • 该插件不仅适用于查询,还可以用于增、删、改操作,确保所有操作都符合租户隔离的要求。
总结

Mybatis-Plus 插件机制通过提供灵活的拦截功能,可以有效地扩展 MyBatis 的功能。通过自定义插件,开发者能够实现如动态 SQL 扩展、SQL 性能监控、数据加密解密等功能。在 SaaS 系统中,使用插件实现租户数据隔离,是一种非常实用的解决方案,可以减少开发工作量,提高系统的可维护性和安全性。此外,针对不需要隔离的表,我们可以在插件中进行智能判断,避免无意义的条件添加,提升系统效率。

相关文章:

Mybatis-Plus 插件机制与自定义插件实现

1. Mybatis-Plus 插件系统概述 Mybatis-Plus 提供了一个简单而强大的插件机制&#xff0c;允许开发者在 MyBatis 执行 SQL 的过程中插入自定义逻辑。通过插件机制&#xff0c;用户可以实现对 SQL 执行过程的拦截和修改。Mybatis-Plus 插件基于 MyBatis 的拦截器模式进行实现&a…...

开源表单、投票、测评平台部署教程

填鸭表单联合宝塔面板深度定制,自宝塔面板 9.2 版本开始,在宝塔面板-软件商店中可以一键部署填鸭表单系统。 简单操作即可拥有属于自己的表单问卷系统,快速赋能业务。即使小白用户也能轻松上手。 社区版体验地址:https://demo.tduckapp.com/home 前端项目地址: tduck-fro…...

行为模式---命令模式

概念 命令模式是一种行为设计模式&#xff0c;它的核心思想就是将请求封装为一个对象&#xff0c;此对象包含与请求相关的所有信息。可以用不同的请求对客户进行参数化。命令模式通过将请求的发送者和接收者解耦&#xff0c;支持请求的排队、记录、撤销等操作。 使用场景 1、…...

zabbix配置邮件告警

目录 实现步骤&#xff1a; 实现目的&#xff1a; 1.在监控端操作&#xff1a; 2.web界面部署 ​​​​​​​实现步骤&#xff1a; 1、在 zabbix服务端配置邮件发送脚本和修改 zabbix服务端配置文件; 2、在 zabbix前端控制台进行相关设置。 实现目的&#xff1a; Zab…...

INI和CSV文件保存

INI文件 INI文件是一种配置文件格式&#xff0c;通常用于Windows操作系统中的应用程序中。 它是一种文本文件&#xff0c;由多个节和键值对组成&#xff0c;用于存储应用程序的配置信息。 INI文件的特点包括&#xff1a; INI文件是一种文本文件&#xff0c;易于编辑和阅读。…...

汽车智能钥匙中PKE低频天线的作用

PKE&#xff08;Passive Keyless Entry&#xff09;即被动式无钥匙进入系统&#xff0c;汽车智能钥匙中PKE低频天线在现代汽车的智能功能和安全保障方面发挥着关键作用&#xff0c;以下是其具体作用&#xff1a; 信号交互与身份认证 低频信号接收&#xff1a;当车主靠近车辆时…...

计算机等级考试

一、计算机等级考试——题库 &#xff08;1&#xff09;选择题 &#xff08;2&#xff09;基本操作题 &#xff08;3&#xff09;上网题 &#xff08;4&#xff09;文字题 &#xff08;5&#xff09;表格题 &#xff08;6&#xff09;演示文稿题 二、计算机等级考试——标准评…...

Geotools中获取Shapefile的属性表格字符集编码的一种方法

目录 前言 1、字符集编码的重要性 2、Geotools 在 GIS 开发中的地位 一、GeoTools的字符集知识 1、字符集的作用 2、shapefile中字符集信息 二、GeoTools中获取字符集的方法 1、默认获取 2、从DataStore中获取 3、从CPG文件中获取 4、生产字符获取实践 三、总结 前言…...

HTTP 与 HTTPS 协议:从基础到安全强化

引言 互联网的消息是如何传递的&#xff1f; 是在路由器上不断进行跳转 IP的目的是在寻址 HTTP 协议&#xff1a;互联网的基石 定义 HTTP&#xff08;英文&#xff1a;HyperText Transfer Protocol&#xff0c;缩写&#xff1a;HTTP&#xff09;&#xff0c;即超文本传输协…...

Scrapy爬虫框架介绍

目录 什么是Scrapy Scrapy核心组件 Scrapy扩展组件 组件交互流程 安装Scrapy Scrapy项目目录结构说明 创建Scrapy项目 创建爬虫 运行爬虫 配置请求头 全局配置请求头 指定爬虫配置请求头 配置管道pipeline 全局配置pipeline 方式一&#xff1a;指定爬虫配置pipe…...

Stable Diffusion模型高清算法模型类详解

Stable Diffusion模型高清算法模型类详细对比表 模型名称核心原理适用场景参数建议显存消耗细节增强度优缺点4x-UltraSharp残差密集块(RDB)结构优化纹理生成真实人像/建筑摄影重绘幅度0.3-0.4&#xff0c;分块尺寸768px★★★★★☆皮肤纹理细腻&#xff0c;但高对比场景易出现…...

软考网络安全口诀

首先&#xff0c;我们来看第一个口诀 “防御为先&#xff0c;安全无小事”。这个口诀强调了网络安全中的防御意识。在软考备考过程中&#xff0c;我们需要深刻理解网络安全不仅仅是技术层面的问题&#xff0c;更是一种全面的防御思维。从网络架构设计到日常运维管理&#xff0…...

Baklib内容中台赋能企业智管

内容中台构建全场景智管 现代企业数字化运营中&#xff0c;全域内容管理能力已成为核心竞争力。通过智能知识引擎驱动的内容中台架构&#xff0c;企业能够实现跨部门、多形态数据的统一归集与动态调度。以某制造企业为例&#xff0c;其利用中台系统将分散在CRM、ERP及内部文档…...

vscode+vue前端开发环境配置

目录 一、安装Vue二、使用vue新建项目 一、安装Vue 在node.js安装好之后&#xff0c; npm config set registry https://registry.npmmirror.com# 安装vue相关工具&#xff0c;webpack用来项目构建、打包、资源整合等。 npm install webpack -g# 安装vue-cli脚手架 npm insta…...

Python项目-基于深度学习的校园人脸识别考勤系统

引言 随着人工智能技术的快速发展&#xff0c;深度学习在计算机视觉领域的应用日益广泛。人脸识别作为其中的一个重要分支&#xff0c;已经在安防、金融、教育等多个领域展现出巨大的应用价值。本文将详细介绍如何使用Python和深度学习技术构建一个校园人脸识别考勤系统&#…...

浅谈C++函数特性

C的函数特性 前言 在C中&#xff0c;函数加入了许多特性&#xff0c;例如&#xff1a;a、函数缺省参数 b、函数重载 c、内联函数 等等……&#xff0c;这里我会和大家详细去探讨这些特性。以及探讨这些特性的一些细节&#xff0c;同时在内联部分&#xff0c;我们还会把C语言的…...

Python----数据分析(Matplotlib三:绘图二:箱图,散点图,饼图,热力图,3D图)

一、箱图 箱图&#xff08;Box Plot&#xff09;&#xff0c;又称为箱形图、箱线图、盒式图、盒状图或盒须图&#xff0c;是一种用于展示数据分布情况的统计图表 箱图通过显示数据的中位数、上下四分位数&#xff08;Q1和Q3&#xff09;、异常值和数据的分布范围&#xff0c;提…...

高性能PHP框架webman爬虫引擎插件,如何爬取数据

文章精选推荐 1 JetBrains Ai assistant 编程工具让你的工作效率翻倍 2 Extra Icons&#xff1a;JetBrains IDE的图标增强神器 3 IDEA插件推荐-SequenceDiagram&#xff0c;自动生成时序图 4 BashSupport Pro 这个ides插件主要是用来干嘛的 &#xff1f; 5 IDEA必装的插件&…...

【2025年后端开发终极指南:云原生、AI融合与性能优化实战】

一、2025年后端开发的五大核心趋势 1. 云原生架构的全面普及 云原生&#xff08;Cloud Native&#xff09;已经成为企业级应用的核心底座。通过容器化技术&#xff08;DockerKubernetes&#xff09;和微服务架构&#xff0c;开发者能够实现应用的快速部署、弹性伸缩和故障自愈…...

健康养生:开启活力人生的钥匙

在这个瞬息万变的时代&#xff0c;人们愈发珍视健康。健康养生&#xff0c;宛如一把神奇的钥匙&#xff0c;为我们打开通往活力人生的大门&#xff0c;全方位呵护身心&#xff0c;提升生活品质。 从饮食层面看&#xff0c;均衡膳食是核心。每餐力求包含碳水化合物、蛋白质、脂…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

加密通信 + 行为分析:运营商行业安全防御体系重构

在数字经济蓬勃发展的时代&#xff0c;运营商作为信息通信网络的核心枢纽&#xff0c;承载着海量用户数据与关键业务传输&#xff0c;其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级&#xff0c;传统安全防护体系逐渐暴露出局限性&a…...

[特殊字符] 手撸 Redis 互斥锁那些坑

&#x1f4d6; 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作&#xff0c;想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁&#xff0c;也顺便跟 Redisson 的 RLock 机制对比了下&#xff0c;记录一波&#xff0c;别踩我踩过…...