Mr. Cappuccino的第56杯咖啡——Mybatis拦截器

Mybatis拦截器

    • 概述
    • 应用场景
    • 项目结构
    • 实现分页查询
    • 其它拦截器的使用

概述

Mybatis允许使用者在映射语句执行过程中的某一些指定的节点进行拦截调用,通过织入拦截器,在不同节点修改一些执行过程中的关键属性,从而影响SQL的生成、执行和返回结果。

默认情况下,Mybatis支持四种对象拦截:

  1. Executor:拦截执行器的方法;
  2. ParameterHandler:拦截参数的处理;
  3. ResultSetHandler:拦截结果集的处理;
  4. StatementHandler:拦截Sql语法构建的处理;

执行顺序:Executor => StatementHandler => ParameterHandler => ResultSetHandler

注:本文代码基于《Mybatis一级缓存&二级缓存》中的“一级缓存(Spring整合Mybatis)”的代码进行调整。

应用场景

  1. 分页查询;
  2. 数据脱敏;
  3. 数据过滤;
  4. 监控Sql语句执行耗时;

项目结构

在这里插入图片描述

实现分页查询

StatementInterceptor.java

package com.mybatis.interceptor;import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import java.lang.reflect.Field;
import java.sql.Connection;
import java.util.Properties;/*** @author honey* @date 2023-08-02 15:25:26*/
@Slf4j
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}),
})
@Component
public class StatementInterceptor implements Interceptor {@Value("${mybatis.page-helper.rule}")private String rule;@Overridepublic Object intercept(Invocation invocation) throws Throwable {StatementHandler statementHandler = (StatementHandler) invocation.getTarget();MetaObject metaObject = SystemMetaObject.forObject(statementHandler);MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();// 判断sql语句的类型switch (sqlCommandType) {case SELECT:extendLimit(statementHandler);break;case INSERT:case UPDATE:case DELETE:case FLUSH:default:break;}log.info("【StatementInterceptor】方法拦截前执行");Object result = invocation.proceed();log.info("【StatementInterceptor】方法拦截后执行");return result;}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {}private void extendLimit(StatementHandler statementHandler) throws NoSuchFieldException, IllegalAccessException {// 获取原生sql语句BoundSql boundSql = statementHandler.getBoundSql();Class<? extends BoundSql> aClass = boundSql.getClass();// 使用反射机制修改原生sql语句Field sql = aClass.getDeclaredField("sql");sql.setAccessible(true);String oldSqlStr = boundSql.getSql();log.info("原生sql语句:{}", oldSqlStr);// 加上分页规则sql.set(boundSql, oldSqlStr + " " + rule);}
}

application.yml

mybatis:page-helper:rule: limit 2

在这里插入图片描述

其它拦截器的使用

ExecutorInterceptor.java

package com.mybatis.interceptor;import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;import java.util.Properties;/*** @author honey* @date 2023-08-02 18:11:28*/
@Slf4j
@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
})
@Component
public class ExecutorInterceptor implements Interceptor {Properties properties;@Overridepublic Object intercept(Invocation invocation) throws Throwable {log.info("【ExecutorInterceptor】方法拦截前执行");Object result = invocation.proceed();log.info("【ExecutorInterceptor】方法拦截后执行");return result;}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {this.properties = properties;}
}

ParameterInterceptor.java

package com.mybatis.interceptor;import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.stereotype.Component;import java.sql.PreparedStatement;
import java.util.Properties;/*** @author honey* @date 2023-08-02 18:22:15*/
@Slf4j
@Intercepts({@Signature(type = ParameterHandler.class, method = "setParameters", args = {PreparedStatement.class})
})
@Component
public class ParameterInterceptor implements Interceptor {Properties properties;@Overridepublic Object intercept(Invocation invocation) throws Throwable {log.info("【ParameterInterceptor】方法拦截前执行");Object result = invocation.proceed();log.info("【ParameterInterceptor】方法拦截后执行");return result;}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {this.properties = properties;}
}

ResultSetInterceptor.java

package com.mybatis.interceptor;import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.*;
import org.springframework.stereotype.Component;import java.sql.Statement;
import java.util.Properties;/*** @author honey* @date 2023-08-02 18:24:00*/
@Slf4j
@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
@Component
public class ResultSetInterceptor implements Interceptor {Properties properties;@Overridepublic Object intercept(Invocation invocation) throws Throwable {log.info("【ResultSetInterceptor】方法拦截前执行");Object result = invocation.proceed();log.info("【ResultSetInterceptor】方法拦截后执行");return result;}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {this.properties = properties;}
}

在这里插入图片描述

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

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

相关文章

项目也能“收纳”?UniPro帮助客户智能管理项目数据

用户是技术产品最终的使用者&#xff0c;他们对产品的需求和期望直接影响着产品的成功与否。通过用户的反馈&#xff0c;开发团队可以深入了解用户的实际需求&#xff0c;将技术的发展方向和优先级与用户需求紧密结合&#xff0c;从而更好地满足市场需求。 UniPro作为国内主流…

wpf 项目中使用 Prism + MaterialDesign

1.通过nuget安装MaterialDesign 2.通过nuget安装Prism 3.修改App.xmal <prism:PrismApplication x:Class"VisionMeasureGlue.App"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/…

应急响应-linux挖矿病毒的实战处置

0x01 服务器现状分析 客户描述服务器卡顿&#xff0c;切通过搜索引擎进去该官网跳转非法页面&#xff0c;但本地访问无异常 0x02 信息收集 通过进程占用情况cpu功率拉满&#xff0c;确定被植入挖矿病毒文件 qq 且存在计划任务update.sh&#xff1a;crontab -l 将该文件上传沙…

C语言案例 99乘法口诀-04

难度2复杂度2 题目&#xff1a;打印99乘法口诀 步骤一&#xff1a;定义程序目标 编写一个C程序&#xff0c;打印99乘法口诀。 步骤二&#xff1a;程序设计 整个程序分别为两个部分&#xff0c;第一部分是使用for循环打印的行数&#xff0c;第二部分是使用for循环控制打印的列…

Gitlab CI/CD笔记-第二天-GitOps的流水线常用关键词(1)

一、常用关键词 在Gitlab项目的根目录需要创建一个 .gitlab-ci.yaml的文件。 这个文件就是定义的流水线。Call :"Pipeline as code" 二、这条流水线怎么写&#xff1f; 一、掌握常用的关键词即可。 1.关键词分类 1.全局关键词 Global Keywards 2.任务关键词…

基于YOLOv7开发构建MSTAR雷达影像目标检测系统

MSTAR&#xff08;Moving and Stationary Target Acquisition and Recognition&#xff09;数据集是一个基于合成孔径雷达&#xff08;Synthetic Aperture Radar&#xff0c;SAR&#xff09;图像的目标检测和识别数据集。它是针对目标检测、机器学习和模式识别算法的研究和评估…

On Evaluation of Embodied Navigation Agents 论文阅读

论文信息 题目&#xff1a;On Evaluation of Embodied Navigation Agents 作者&#xff1a;Peter Anderson&#xff0c;Angel Chang 来源&#xff1a;arXiv 时间&#xff1a;2018 Abstract 过去两年&#xff0c;导航方面的创造性工作激增。这种创造性的输出产生了大量有时不…

Typescript - 索引签名

目录 1&#xff0c;什么是索引签名1&#xff0c;js 中使用对象的属性2&#xff0c;ts 中的索引签名3&#xff0c;扩展索引签名定义的类型 2&#xff0c;与 Record 对比3&#xff0c;遇到的问题1&#xff0c;索引 key 的类型问题&#xff0c;keyof2&#xff0c;索引 key 的类型问…

烧结钕铁硼的物理性能

烧结钕铁硼永磁体作为核心功能部件&#xff0c;广泛应用在电机、电声、磁吸和传感器等仪器设备中。磁体在服役过程中&#xff0c;会受到机械力、冷热变化、交变电磁场等环境因素&#xff0c;如果发生环境失效&#xff0c;将会严重影响设备的功用&#xff0c;造成巨大的损失。因…

QT - 建立页面

一、生成页面 二、实现 1.LineEdit 是一个单行输入文本框&#xff0c;为用户提供了比较多的编辑功能&#xff0c;例如选择复制、粘贴。 修改echomode属性为password Push Button(常规按钮) 三、程序 声明全局变量&#xff0c;属于MainWindow private: // 定义了一个指向Ma…

24届近5年上海交通大学自动化考研院校分析

今天给大家带来的是上海交通大学控制考研分析 满满干货&#xff5e;还不快快点赞收藏 一、上海交通大学 学校简介 上海交通大学是我国历史最悠久、享誉海内外的高等学府之一&#xff0c;是教育部直属并与上海市共建的全国重点大学。经过120多年的不懈努力&#xff0c;上海交…

【Linux旅行记】第一个小程序“进度条“!

文章目录 一、预备知识1.1回车换行1.2缓冲区 二、倒计时三、进度条3.1普通版本源代码3.2高级版本源代码 &#x1f340;小结&#x1f340; &#x1f389;博客主页&#xff1a;小智_x0___0x_ &#x1f389;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &…

Vue3自定义简单的Swiper滑动组件-触控板滑动鼠标滑动左右箭头滑动-demo

代码实现了一个基本的滑动功能&#xff0c;通过鼠标按下、鼠标松开和鼠标移动事件来监听滑动操作。 具体实现逻辑如下&#xff1a; 在 onMounted 钩子函数中&#xff0c;我们为滚动容器添加了三个事件监听器&#xff1a;mousedown 事件&#xff1a;当鼠标按下时&#xff0c;设置…

Netty面试题1

计算机网络模型 OSI采用了分层的结构化技术&#xff0c;共分七层&#xff0c; 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层 。 Open System Interconnect 简称OSI&#xff0c;是国际标准化组织(ISO)和国际电报电话咨询委员会(CCITT)联合制定的开放系统互连参…

超详情的开源知识库管理系统- mm-wiki的安装和使用

背景&#xff1a;最近公司需要一款可以记录公司内部文档信息&#xff0c;一些只是累计等&#xff0c;通过之前的经验积累&#xff0c;立马想到了 mm-wiki&#xff0c;然后就给公司搭建了一套&#xff0c;分享一下安装和使用说明&#xff1a; 当前市场上众多的优秀的文档系统百…

6.s081/6.1810(Fall 2022)Lab4: Traps

文章目录 前言其他篇章参考链接0. 环境搭建1. RISC-V assembly (easy)1.0 简介1.1 Q11.2 Q21.3 Q31.4 Q41.5 Q51.6 Q6 2. Backtrace (moderate)2.1 简单分析2.2 实现2.3 测试 3. Alarm (hard)3.1 简单分析3.2 test0: invoke handler3.2.1 添加调用3.2.2 获取参数3.2.3 处理中断…

服务器硬件、部署LNMP动态网站、部署wordpress、配置web与数据库服务分离、配置额外的web服务器

day01 day01项目实战目标单机安装基于LNMP结构的WordPress网站基本环境准备配置nginx配置数据库服务部署wordpressweb与数据库服务分离准备数据库服务器迁移数据库配置额外的web服务器 项目实战目标 主机名IP地址client01192.168.88.10/24web1192.168.88.11/24web2192.168.88…

Baumer工业相机堡盟工业相机如何通过BGAPISDK获取相机接口数据吞吐量(C++)

Baumer工业相机堡盟工业相机如何通过BGAPISDK里函数来获取相机当前数据吞吐量&#xff08;C&#xff09; Baumer工业相机Baumer工业相机的数据吞吐量的技术背景CameraExplorer如何查看相机吞吐量信息在BGAPI SDK里通过函数获取相机接口吞吐量 Baumer工业相机通过BGAPI SDK获取数…

STM32 CubeMX USB_(HID 鼠标和键盘)

STM32 CubeMX STM32 CubeMX USB_HID&#xff08;HID 鼠标和键盘&#xff09; STM32 CubeMX前言 《鼠标》一、STM32 CubeMX 设置USB时钟设置USB使能UBS功能选择 二、代码部分添加代码鼠标发送给PC的数据解析实验效果 《键盘》STM32 CubeMX 设置&#xff08;同上&#xff09;代码…

睡眠助手/白噪音/助眠夜曲微信小程序源码下载 附教程

睡眠助手/白噪音/助眠夜曲微信小程序源码 附教程 支持分享海报 支持暗黑模式 包含了音频数据 最近很火的助眠小程序&#xff0c;前端vue&#xff0c;可以打包H5&#xff0c;APP&#xff0c;小程序 后台可以设置流量主广告&#xff0c;非常不错的源码 代码完整 完美运营 搭配无…