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

MyBatis 插件机制、分页插件如何实现的

MyBatis 插件机制允许开发者在 SQL 执行的各个阶段(如预处理、执行、结果处理等)中插入自定义逻辑,从而实现对 MyBatis 行为的扩展和增强。以下是 MyBatis 插件运行原理的详细介绍:

插件接口

MyBatis 插件通过实现 org.apache.ibatis.plugin.Interceptor 接口来定义。这个接口有两个主要方法:

  1. intercept 方法:定义具体的拦截逻辑。
  2. plugin 方法:用于创建代理对象。
  3. 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. 插件的创建和执行流程
  1. 插件的注册和加载

    • 在 MyBatis 初始化过程中,配置文件中的插件信息会被加载。
    • MyBatis 会创建插件实例,并调用 setProperties 方法设置插件的属性。
  2. 插件的包装

    • 在创建核心组件(如 Executor、ParameterHandler 等)时,MyBatis 会调用插件的 plugin 方法。
    • 插件的 plugin 方法通常使用 Plugin.wrap 方法创建动态代理对象,代理目标对象的指定方法。
  3. 方法的拦截和执行

    • 当代理对象的方法被调用时,代理逻辑会判断该方法是否在拦截点范围内。
    • 如果在拦截点范围内,代理逻辑会调用插件的 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 接口的 updatequery 方法,打印方法执行前后的消息。

小结

MyBatis 插件机制通过动态代理模式,实现对 SQL 执行各个阶段的拦截和扩展。开发者可以根据业务需求,自定义插件逻辑,实现 SQL 执行的增强和优化。


分页插件的原理

分页插件是 MyBatis 插件的一种常见应用,主要用于实现数据库的物理分页。其原理如下:

  1. 拦截 SQL 处理过程
    分页插件通常会拦截 StatementHandlerprepare 方法,在 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) {}
    }
    
  2. 分页参数传递
    分页参数通常通过线程本地变量(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();}
    }
    
  3. 分页 SQL 生成
    拦截器拦截到 SQL 语句后,会根据分页参数生成分页 SQL。常见的分页 SQL 生成方式是使用 LIMIT 关键字(适用于 MySQL 等数据库)。

  4. 重写 SQL
    拦截器拦截到原始 SQL 后,会重写 SQL 语句,将其替换为分页 SQL,然后再交给 MyBatis 执行。

MyBatis 插件通过拦截器机制实现,允许在执行 SQL 语句的过程中插入自定义逻辑。分页插件利用这一机制,在 SQL 语句执行前对其进行重写,生成分页 SQL,以实现物理分页的效果。通过线程本地变量传递分页参数,确保分页逻辑在多线程环境下的安全性。

相关文章:

MyBatis 插件机制、分页插件如何实现的

MyBatis 插件机制允许开发者在 SQL 执行的各个阶段&#xff08;如预处理、执行、结果处理等&#xff09;中插入自定义逻辑&#xff0c;从而实现对 MyBatis 行为的扩展和增强。以下是 MyBatis 插件运行原理的详细介绍&#xff1a; 插件接口 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工作性价比计算器

工作性价比&#xff1d;平均日新x综合环境系数/35 x(工作时长&#xff0b;通勤时长—0.5 x摸鱼时长) x学历系数 如果代码中的公式不对&#xff0c;请指正 效果图 源代码 <!DOCTYPE html> <html> <head> <style> .calculator { width: 300px; padd…...

Linux:基础命令学习

目录 一、ls命令 实例&#xff1a;-l以长格式显示文件和目录信息 实例&#xff1a;-F根据文件类型在列出的文件名称后加一符号 实例&#xff1a; -R 递归显示目录中的所有文件和子目录。 实例&#xff1a; 组合使用 Home目录和工作目录 二、目录修改和查看命令 三、mkd…...

遇到Websocket就不会测了?别慌,学会这个Jmeter插件轻松解决....

websocket 是一种双向通信协议&#xff0c;在建立连接后&#xff0c;websocket服务端和客户端都能主动向对方发送或者接收数据&#xff0c;而在http协议中&#xff0c;一个request只能有一个response&#xff0c;而且这个response也是被动的&#xff0c;不能主动发起。 websoc…...

高性能 Java 本地缓存 Caffeine 框架介绍及在 SpringBoot 中的使用

在现代应用程序中&#xff0c;缓存是一种重要的性能优化技术&#xff0c;它可以显著减少数据访问延迟&#xff0c;降低服务器负载&#xff0c;提高系统的响应速度。特别是在高并发的场景下&#xff0c;合理地使用缓存能够有效提升系统的稳定性和效率。 Caffeine 是一个高性能的…...

Http 和 Https 的区别(图文详解)

在现代网络通信中&#xff0c;保护数据的安全性和用户的隐私是至关重要的。HTTP&#xff08;Hypertext Transfer Protocol&#xff09;和 HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;是两种常见的网络通信协议&#xff0c;但它们在数据保护方面的能力存在…...

DP学习——外观模式

学而时习之&#xff0c;温故而知新。 外观模式 角色 2个角色&#xff0c;外观类&#xff0c;子系统类。 个人理解 感觉就是对外接口封装&#xff0c;这个是封装一个功能的对外接口&#xff0c;越简单越好&#xff0c;提供给第三方用。 应用场景 封装为对外库时&#xff…...

Vue3 + Vite 打包引入图片错误

1. 具体报错 报错信息 报错代码 2. 解决方法 改为import引入&#xff0c;注意src最好引用为符引入&#xff0c;不然docker部署的时候可能也会显示不了 <template><img :src"loginBg" alt""> </template><script langts setup> …...

搭建NFS、web、dns服务器

目录 1、搭建一个nfs服务器&#xff0c;客户端可以从该服务器的/share目录上传并下载文件 服务端配置&#xff1a; 客户端测试&#xff1a; 2、搭建一个Web服务器&#xff0c;客户端通过www.haha.com访问该网站时能够看到内容:this is haha 服务端配置&#xff1a; 客户端…...

C++的UI框架和开源项目介绍

文章目录 1.QT2.wxWidgets3.Dear ImGui 1.QT QT的开源项目&#xff1a;QGIS&#xff08;地理信息系统&#xff09; https://github.com/qgis/QGIS?tabreadme-ov-file 2.wxWidgets wxWidgets的开源项目&#xff1a;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

想要实现前端对表格中的数据进行导出&#xff0c;这里推荐使用xlsx这个依赖库实现。 1、安装 pnpm install xlsx 2、使用 import * as XLSX from "xlsx"; 直接在组件里导入XLSX库&#xff0c;然后给表格table通过ref创建响应式数据拿到table实例&#xff0c;将实…...

【算法】分布式共识Paxos

一、引言 在分布式系统中&#xff0c;一致性是至关重要的一个问题。Paxos算法是由莱斯利兰伯特&#xff08;Leslie Lamport&#xff09;在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&#xff08;第5版&#xff09; 练习 15.28 练习 15.28 定义一个存放Quote对象的vector&#xff0c;将Bulk_quote对象传入其中。计算vector中所有元素总的net_price。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块&am…...

Midjourney绘画提示词精选

Midjourney绘画提示词精选 在探索Midjourney这一强大的AI绘画工具时&#xff0c;选择合适的提示词是创作出令人惊艳作品的关键。这些提示词不仅能够帮助Midjourney理解你的创作意图&#xff0c;还能引导它生成出符合你期望的图像。以下是对Midjourney绘画提示词的精选与解析&a…...

Kylin中的RBAC:为大数据安全加把锁

Kylin中的RBAC&#xff1a;为大数据安全加把锁 Apache Kylin是一个开源的分布式分析引擎&#xff0c;旨在为Hadoop平台提供快速的大数据量SQL查询能力。随着企业对数据安全和访问控制需求的增加&#xff0c;基于角色的访问控制&#xff08;Role-Based Access Control&#xff…...

DDoS 攻击下的教育网站防护策略

随着互联网的普及&#xff0c;教育网站成为学生和教师获取信息、进行在线学习的重要平台。然而&#xff0c;这些网站也成为了网络攻击的目标&#xff0c;尤其是分布式拒绝服务&#xff08;DDoS&#xff09;攻击。本文将探讨DDoS攻击对教育网站的影响&#xff0c;并提出一系列有…...

Android13以太网静态IP不保存的问题

最近在做Amlogic T982的样机&#xff0c;关于以太网部分&#xff0c;系统Settings只有一个Ethernet的条目&#xff0c;没有其他任何信息&#xff0c;什么以太网mac地址&#xff0c;开关&#xff0c;IP地址&#xff0c;子网掩码&#xff0c;默认网关&#xff0c;dns, 设置代理&a…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

Java毕业设计:WML信息查询与后端信息发布系统开发

JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发&#xff0c;实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构&#xff0c;服务器端使用Java Servlet处理请求&#xff0c;数据库采用MySQL存储信息&#xff0…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

uniapp 实现腾讯云IM群文件上传下载功能

UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中&#xff0c;群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS&#xff0c;在uniapp中实现&#xff1a; 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...