MyBatis 插件机制、分页插件如何实现的
MyBatis 插件机制允许开发者在 SQL 执行的各个阶段(如预处理、执行、结果处理等)中插入自定义逻辑,从而实现对 MyBatis 行为的扩展和增强。以下是 MyBatis 插件运行原理的详细介绍:
插件接口
MyBatis 插件通过实现 org.apache.ibatis.plugin.Interceptor 接口来定义。这个接口有两个主要方法:
intercept方法:定义具体的拦截逻辑。plugin方法:用于创建代理对象。setProperties方法:用于设置插件的属性。
插件配置
在 MyBatis 配置文件中,通过 plugin 标签配置插件。例如:
<plugins><plugin interceptor="com.example.MyInterceptor"><property name="someProperty" value="someValue"/></plugin>
</plugins>
插件运行原理
1. 拦截点
MyBatis 提供了四个拦截点,分别对应 Executor、ParameterHandler、ResultSetHandler 和 StatementHandler 接口的方法:
-
Executor:负责执行 SQL 语句。
update:执行更新语句。query:执行查询语句。flushStatements:刷新语句。commit:提交事务。rollback:回滚事务。
-
ParameterHandler:负责处理 SQL 参数。
getParameterObject:获取参数对象。setParameters:设置参数。
-
ResultSetHandler:负责处理结果集。
handleResultSets:处理结果集。handleOutputParameters:处理输出参数。
-
StatementHandler:负责处理 SQL 语句。
prepare:准备 SQL 语句。parameterize:设置 SQL 语句参数。batch:批处理 SQL 语句。update:执行更新语句。query:执行查询语句。
2. 插件的创建和执行流程
-
插件的注册和加载:
- 在 MyBatis 初始化过程中,配置文件中的插件信息会被加载。
- MyBatis 会创建插件实例,并调用
setProperties方法设置插件的属性。
-
插件的包装:
- 在创建核心组件(如 Executor、ParameterHandler 等)时,MyBatis 会调用插件的
plugin方法。 - 插件的
plugin方法通常使用Plugin.wrap方法创建动态代理对象,代理目标对象的指定方法。
- 在创建核心组件(如 Executor、ParameterHandler 等)时,MyBatis 会调用插件的
-
方法的拦截和执行:
- 当代理对象的方法被调用时,代理逻辑会判断该方法是否在拦截点范围内。
- 如果在拦截点范围内,代理逻辑会调用插件的
intercept方法执行自定义逻辑。 - 插件可以选择继续调用目标方法,或者修改返回结果。
插件示例
以下是一个简单的 MyBatis 插件示例:
package com.example;import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;import java.util.Properties;@Intercepts({@Signature(type = org.apache.ibatis.executor.Executor.class, method = "update", args = {org.apache.ibatis.mapping.MappedStatement.class, Object.class}),@Signature(type = org.apache.ibatis.executor.Executor.class, method = "query", args = {org.apache.ibatis.mapping.MappedStatement.class, Object.class, org.apache.ibatis.session.RowBounds.class, org.apache.ibatis.session.ResultHandler.class})
})
public class MyInterceptor implements Interceptor {private Properties properties;@Overridepublic Object intercept(Invocation invocation) throws Throwable {// 在这里添加拦截逻辑System.out.println("Before method execution");Object returnValue = invocation.proceed(); // 调用目标方法System.out.println("After method execution");return returnValue;}@Overridepublic Object plugin(Object target) {// 创建代理对象return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {// 设置插件属性this.properties = properties;}
}
在这个示例中,插件拦截了 Executor 接口的 update 和 query 方法,打印方法执行前后的消息。
小结
MyBatis 插件机制通过动态代理模式,实现对 SQL 执行各个阶段的拦截和扩展。开发者可以根据业务需求,自定义插件逻辑,实现 SQL 执行的增强和优化。
分页插件的原理
分页插件是 MyBatis 插件的一种常见应用,主要用于实现数据库的物理分页。其原理如下:
-
拦截 SQL 处理过程:
分页插件通常会拦截StatementHandler的prepare方法,在 SQL 语句执行前进行分页处理。@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})}) public class PaginationInterceptor implements Interceptor {@Overridepublic Object intercept(Invocation invocation) throws Throwable {// 获取目标对象StatementHandler statementHandler = (StatementHandler) invocation.getTarget();// 获取原始的 SQLBoundSql boundSql = statementHandler.getBoundSql();String originalSql = boundSql.getSql();// 获取分页参数Page page = PageHelper.getPage();int offset = page.getOffset();int limit = page.getLimit();// 生成分页 SQLString paginatedSql = originalSql + " LIMIT " + offset + "," + limit;// 重新设置分页 SQLReflectUtil.setFieldValue(boundSql, "sql", paginatedSql);return invocation.proceed();}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {} } -
分页参数传递:
分页参数通常通过线程本地变量(ThreadLocal)来传递,保证在多线程环境下数据的隔离性。一个常见的做法是使用PageHelper类来设置分页参数。public class PageHelper {private static final ThreadLocal<Page> LOCAL_PAGE = new ThreadLocal<>();public static void startPage(int pageNum, int pageSize) {LOCAL_PAGE.set(new Page(pageNum, pageSize));}public static Page getPage() {return LOCAL_PAGE.get();} } -
分页 SQL 生成:
拦截器拦截到 SQL 语句后,会根据分页参数生成分页 SQL。常见的分页 SQL 生成方式是使用LIMIT关键字(适用于 MySQL 等数据库)。 -
重写 SQL:
拦截器拦截到原始 SQL 后,会重写 SQL 语句,将其替换为分页 SQL,然后再交给 MyBatis 执行。
MyBatis 插件通过拦截器机制实现,允许在执行 SQL 语句的过程中插入自定义逻辑。分页插件利用这一机制,在 SQL 语句执行前对其进行重写,生成分页 SQL,以实现物理分页的效果。通过线程本地变量传递分页参数,确保分页逻辑在多线程环境下的安全性。
相关文章:
MyBatis 插件机制、分页插件如何实现的
MyBatis 插件机制允许开发者在 SQL 执行的各个阶段(如预处理、执行、结果处理等)中插入自定义逻辑,从而实现对 MyBatis 行为的扩展和增强。以下是 MyBatis 插件运行原理的详细介绍: 插件接口 MyBatis 插件通过实现 org.apache.i…...
CentOS6.0安装telnet-server启用telnet服务
CentOS6.0安装telnet-server启用telnet服务 一步到位 fp"/etc/yum.repos.d" ; cp -a ${fp} ${fp}.$(date %0y%0m%0d%0H%0M%0S).bkup echo [base] nameCentOS-$releasever - Base baseurlhttp://mirrors.163.com/centos-vault/6.0/os/$basearch/http://mirrors.a…...
H5+CSS+JS工作性价比计算器
工作性价比=平均日新x综合环境系数/35 x(工作时长+通勤时长—0.5 x摸鱼时长) x学历系数 如果代码中的公式不对,请指正 效果图 源代码 <!DOCTYPE html> <html> <head> <style> .calculator { width: 300px; padd…...
Linux:基础命令学习
目录 一、ls命令 实例:-l以长格式显示文件和目录信息 实例:-F根据文件类型在列出的文件名称后加一符号 实例: -R 递归显示目录中的所有文件和子目录。 实例: 组合使用 Home目录和工作目录 二、目录修改和查看命令 三、mkd…...
遇到Websocket就不会测了?别慌,学会这个Jmeter插件轻松解决....
websocket 是一种双向通信协议,在建立连接后,websocket服务端和客户端都能主动向对方发送或者接收数据,而在http协议中,一个request只能有一个response,而且这个response也是被动的,不能主动发起。 websoc…...
高性能 Java 本地缓存 Caffeine 框架介绍及在 SpringBoot 中的使用
在现代应用程序中,缓存是一种重要的性能优化技术,它可以显著减少数据访问延迟,降低服务器负载,提高系统的响应速度。特别是在高并发的场景下,合理地使用缓存能够有效提升系统的稳定性和效率。 Caffeine 是一个高性能的…...
Http 和 Https 的区别(图文详解)
在现代网络通信中,保护数据的安全性和用户的隐私是至关重要的。HTTP(Hypertext Transfer Protocol)和 HTTPS(Hypertext Transfer Protocol Secure)是两种常见的网络通信协议,但它们在数据保护方面的能力存在…...
DP学习——外观模式
学而时习之,温故而知新。 外观模式 角色 2个角色,外观类,子系统类。 个人理解 感觉就是对外接口封装,这个是封装一个功能的对外接口,越简单越好,提供给第三方用。 应用场景 封装为对外库时ÿ…...
Vue3 + Vite 打包引入图片错误
1. 具体报错 报错信息 报错代码 2. 解决方法 改为import引入,注意src最好引用为符引入,不然docker部署的时候可能也会显示不了 <template><img :src"loginBg" alt""> </template><script langts setup> …...
搭建NFS、web、dns服务器
目录 1、搭建一个nfs服务器,客户端可以从该服务器的/share目录上传并下载文件 服务端配置: 客户端测试: 2、搭建一个Web服务器,客户端通过www.haha.com访问该网站时能够看到内容:this is haha 服务端配置: 客户端…...
C++的UI框架和开源项目介绍
文章目录 1.QT2.wxWidgets3.Dear ImGui 1.QT QT的开源项目:QGIS(地理信息系统) https://github.com/qgis/QGIS?tabreadme-ov-file 2.wxWidgets wxWidgets的开源项目:filezilla https://svn.filezilla-project.org/svn/ wxWidg…...
SpringBoot连接PostgreSQL+MybatisPlus入门案例
项目结构 一、Java代码 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://mave…...
vue3里将table表格中的数据导出为excel
想要实现前端对表格中的数据进行导出,这里推荐使用xlsx这个依赖库实现。 1、安装 pnpm install xlsx 2、使用 import * as XLSX from "xlsx"; 直接在组件里导入XLSX库,然后给表格table通过ref创建响应式数据拿到table实例,将实…...
【算法】分布式共识Paxos
一、引言 在分布式系统中,一致性是至关重要的一个问题。Paxos算法是由莱斯利兰伯特(Leslie Lamport)在1990年提出的一种解决分布式系统中一致性问题的算法。 二、算法原理 Paxos算法的目标是让一个分布式系统中的多个节点就某个值达成一致。算…...
软考:软件设计师 — 5.计算机网络
五. 计算机网络 1. OSI 七层模型 层次名称主要功能主要设备及协议7应用层实现具体的应用功能 POP3、FTP、HTTP、Telent、SMTP DHCP、TFTP、SNMP、DNS 6表示层数据的格式与表达、加密、压缩5会话层建立、管理和终止会话4传输层端到端的连接TCP、UDP3网络层分组传输和路由选择 三…...
C++ //练习 15.28 定义一个存放Quote对象的vector,将Bulk_quote对象传入其中。计算vector中所有元素总的net_price。
C Primer(第5版) 练习 15.28 练习 15.28 定义一个存放Quote对象的vector,将Bulk_quote对象传入其中。计算vector中所有元素总的net_price。 环境:Linux Ubuntu(云服务器) 工具:vim 代码块&am…...
Midjourney绘画提示词精选
Midjourney绘画提示词精选 在探索Midjourney这一强大的AI绘画工具时,选择合适的提示词是创作出令人惊艳作品的关键。这些提示词不仅能够帮助Midjourney理解你的创作意图,还能引导它生成出符合你期望的图像。以下是对Midjourney绘画提示词的精选与解析&a…...
Kylin中的RBAC:为大数据安全加把锁
Kylin中的RBAC:为大数据安全加把锁 Apache Kylin是一个开源的分布式分析引擎,旨在为Hadoop平台提供快速的大数据量SQL查询能力。随着企业对数据安全和访问控制需求的增加,基于角色的访问控制(Role-Based Access Controlÿ…...
DDoS 攻击下的教育网站防护策略
随着互联网的普及,教育网站成为学生和教师获取信息、进行在线学习的重要平台。然而,这些网站也成为了网络攻击的目标,尤其是分布式拒绝服务(DDoS)攻击。本文将探讨DDoS攻击对教育网站的影响,并提出一系列有…...
Android13以太网静态IP不保存的问题
最近在做Amlogic T982的样机,关于以太网部分,系统Settings只有一个Ethernet的条目,没有其他任何信息,什么以太网mac地址,开关,IP地址,子网掩码,默认网关,dns, 设置代理&a…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
