Mybatis 拦截器

MyBatis 拦截器(Interceptor)是 MyBatis 提供的一种强大机制,允许开发者在 SQL 映射语句执行过程中的特定节点进行拦截和定制处理。通过实现 org.apache.ibatis.plugin.Interceptor 接口并注册到 MyBatis 的配置文件中,可以插入自定义的逻辑来改变或增强 MyBatis 的默认行为。

使用样例:统计(查询,更新,批量更新)SQL执行次数及用时

import com.zhangziwa.practisesvr.utils.log.LogContext;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.springframework.stereotype.Component;

import java.sql.Statement;

@Intercepts({
        @Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class}),
        @Signature(type = StatementHandler.class, method = "update", args = {Statement.class}),
        @Signature(type = StatementHandler.class, method = "batch", args = {Statement.class})})
@Component
public class SqlExecuteInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.err.println("***SqlExecuteInterceptor.intercept***");

        long startTime = System.currentTimeMillis();
        try {
            return invocation.proceed();
        } finally {
            long executionCost = System.currentTimeMillis() - startTime;
            LogContext.incrementSqlCount();
            LogContext.incrementSqlCost(executionCost);
        }
    }
}

使用样例:统计查询结果的数据量

import com.zhangziwa.practisesvr.utils.log.LogContext;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.springframework.stereotype.Component;

import java.sql.Statement;
import java.util.Collection;

@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})})
@Component
public class SqlReadRowInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object proceed = invocation.proceed();
        if (proceed instanceof Collection) {
            LogContext.incrementSqlSearchedRowCount(((Collection<?>) proceed).size());
        } else {
            LogContext.incrementSqlSearchedRowCount(0);
        }
        return proceed;
    }
}

在这里插入图片描述

@Signature注解的type属性用于指定要拦截的接口类型,它可以是以下几种类型的类::
Executor (执行器): 拦截org.apache.ibatis.executor.Executor接口的方法,主要用于处理SQL语句的执行过程,包括查询、更新、插入和删除等操作。 例如,它可以用来控制事务的边界、记录日志或者进行额外的数据验证。

ParameterHandler (参数处理器): 拦截org.apache.ibatis.mapping.ParameterHandler接口的方法,负责设置SQL预编译语句中的参数值 拦截此类方法可以对传入的参数做进一步的处理,如加密、解密、类型转换等。

StatementHandler (SQL处理器): 拦截org.apache.ibatis.mapping.StatementHandler接口的方法,用于处理SQL语法构建相关的工作。 如动态SQL的解析与拼接、添加额外的查询条件等。

ResultSetHandler (结果集处理器): 拦截org.apache.ibatis.resultset.ResultSetHandler接口的方法,用于处理数据库返回的结果集,将结果集中的数据映射到Java对象上。 在拦截这个阶段时,可以对结果进行后处理、自定义结果映射规则或增加缓存逻辑等。

拦截器的执行顺序是按照Executor -> ParameterHandler -> StatementHandler -> ResultSetHandler 的顺序进行.
如果有多个相同类型的拦截器,则按照添加到SqlSessionFactory中的逆序来执行。

在这里插入图片描述

@Signature注解的method用于指定需要拦截的具体方法名称,它可以是以下几种类型的类:

# 对于Executor接口,可能的方法包括:
    int update(MappedStatement var1, Object var2) throws SQLException;
    <E> List<E> query(MappedStatement var1, Object var2, RowBounds var3, ResultHandler var4, CacheKey var5, BoundSql var6) throws SQLException;
    <E> List<E> query(MappedStatement var1, Object var2, RowBounds var3, ResultHandler var4) throws SQLException;
    <E> Cursor<E> queryCursor(MappedStatement var1, Object var2, RowBounds var3) throws SQLException;
    List<BatchResult> flushStatements() throws SQLException;
    void commit(boolean var1) throws SQLException;
    void rollback(boolean var1) throws SQLException;
    CacheKey createCacheKey(MappedStatement var1, Object var2, RowBounds var3, BoundSql var4);
    boolean isCached(MappedStatement var1, CacheKey var2);
    void clearLocalCache();
    void deferLoad(MappedStatement var1, MetaObject var2, String var3, CacheKey var4, Class<?> var5);
    Transaction getTransaction();
    void close(boolean var1);
    boolean isClosed();
    void setExecutorWrapper(Executor var1);

# 对于ParameterHandler接口,可能的方法是:
    Object getParameterObject();
    void setParameters(PreparedStatement var1) throws SQLException;

# 对于StatementHandler接口,可能的方法包括:
    Statement prepare(Connection var1, Integer var2) throws SQLException;
    void parameterize(Statement var1) throws SQLException;
    void batch(Statement var1) throws SQLException;
    int update(Statement var1) throws SQLException;
    <E> List<E> query(Statement var1, ResultHandler var2) throws SQLException;
    <E> Cursor<E> queryCursor(Statement var1) throws SQLException;
    BoundSql getBoundSql();
    ParameterHandler getParameterHandler();

# 对于ResultSetHandler接口,可能的方法有:
    <E> List<E> handleResultSets(Statement var1) throws SQLException;
    <E> Cursor<E> handleCursorResultSets(Statement var1) throws SQLException;
    void handleOutputParameters(CallableStatement var1) throws SQLException;

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python开发实例 – Lambda表达式

Python开发实例 – Lambda表达式 Python Development Examples – Lambda expression By JacksonML 普通的函数我们很常用&#xff0c;只需要通过 def 声明&#xff0c;并且产生一段代码&#xff0c;包含&#xff08;但不限于&#xff09;参数&#xff0c;返回&#xff08;或…

解决:‘chromedriver’ executable needs to be in PATH

解决&#xff1a;chromedriver’ executable needs to be in PATH 文章目录 解决&#xff1a;chromedriver’ executable needs to be in PATH背景报错问题报错翻译报错位置代码报错原因解决方法方法一&#xff1a;检查python安装路径有没有添加到环境变量里面方法二&#xff1…

element-ui 树形控件 实现点击某个节点获取本身节点和底下所有的子节点数据

1、需求&#xff1a;点击树形控件中的某个节点&#xff0c;需要拿到它本身和底下所有的子节点的id 1、树形控件代码 <el-tree:data"deptOptions"node-click"getVisitCheckedNodes"ref"target_tree_Speech"node-key"id":default-ex…

漏洞复现-万户OA text2Html 任意文件读取(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

MIT_线性代数笔记:线性代数常用计算公式

目录 1.矩阵的加法和数乘2.矩阵的乘法3.转置 Transposes 相关运算 1.矩阵的加法和数乘 2.矩阵的乘法 1)标准方法&#xff08;行乘以列&#xff09; 矩阵乘法的标准计算方法是通过矩阵 A 第 i 行的行向量和矩阵 B 第 j 列的列向量点积得到 cij。即我们常说的点积&#xff0c;也…

华清远见作业第三十二天——C++(第一天)

思维导图&#xff1a; 提示并输入一个字符串&#xff0c;统计字符中大写、小写个数、空格个数以及其他字符个数要求使用C风格完成。 代码&#xff1a; #include <iostream> #include<array> using namespace std;int main() {string str;cout << "请输…

Python Flask与APScheduler构建简易任务监控

1. Flask Web Flask诞生于2010年&#xff0c;是用Python语言&#xff0c;基于Werkzeug工具箱编写的轻量级、灵活的Web开发框架&#xff0c;非常适合初学者或小型到中型的 Web 项目。 Flask本身相当于一个内核&#xff0c;其他几乎所有的功能都要用到扩展&#xff08;邮件扩展…

【异常收集】IDEA启动项目遇到的异常汇总,包括插件异常,版本依赖异常,启动异常等以及对应的解决办法

该文章旨在记录开发中遇到的一些异常&#xff0c;以供遇到似错误进行参考修改 一、项目在多个环境下切换&#xff0c;有一次启动后编译失败&#xff0c;报异常 背景&#xff1a;项目在不同环境下有对应的分支&#xff0c;切换分支后运行项目&#xff0c;报错如下 错误:Kotlin:…

vivado DDS学习

实现DDS通常有两种方式&#xff0c;一种是读取ROM存放的正弦/余弦信号的查表法&#xff0c;另一种是用DDS IP核。这篇学习笔记中&#xff0c;我们要讲解说明的是VIVADO DDS IP核的应用。 目前本篇默认Phase Generator and SIN/COS LUT&#xff08;DDS&#xff09;的standard模式…

102.乐理基础-五线谱-高音谱号

内容参考于&#xff1a;三分钟音乐社 上一个内容&#xff1a;五线谱的构造、谱号是什么-CSDN博客 谱号一共需要学习和了解四种&#xff0c;如下图&#xff1a;要牢牢掌握的是高音谱号和低音谱号这两种&#xff0c;如图1所示 首先高音谱号&#xff1a; 它大致范围&#xff0c;…

SpringBoot中集成XXL-JOB分布式任务调度平台,轻量级、低侵入实现定时任务

场景 XXL-JOB 分布式任务调度平台XXL-JOB XXL-JOB是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。 特性&#xff1a; 1、简单&#xff1a;支持通过Web页面对任务进行CRUD操作&#xff0c;操作简单&#xff0c;一分钟上手&…

【51单片机】蜂鸣器实验和动态数码管实验

目录 蜂鸣器实验蜂鸣器介绍硬件设计软件设计 动态数码管实验多位数码管简介74HC245 芯片简介74HC138 芯片简介 硬件设计软件设计 橙色 蜂鸣器实验 蜂鸣器介绍 蜂鸣器采用直流电压供电&#xff0c;分为压电式蜂鸣器和电磁式蜂鸣器两种类型。 无论是压电式蜂鸣器还是电磁式蜂…

huggingface高速下载模型的实战代码

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

windows版java版本管理器

概述&#xff1a;大家都知道&#xff0c;身为搞java的&#xff0c;肯定不止一个java版本&#xff0c;这里我将讲解用一个工具来解决切换版本问题。至于linux管理java版本的&#xff0c;我也有一篇文章专门讲这个的。 用sdkman在linux上管理多个java版本-CSDN博客 官网&#x…

搭建nginx图片服务器

&#xff08;1&#xff09;将图片存储于/home/data/images目录&#xff1b; &#xff08;2&#xff09;配置nginx.conf user nginx; worker_processes 4;error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid;events {worker_connections 10000; }ht…

【Deeplabv3+】Ubutu18.04中使用pytorch复现Deeplabv3+第三步)-----CityscapesScripts生成自己的标签

本文是在前面两篇文章的基础上&#xff0c;讲解如何更改训练数据集颜色&#xff0c;需要与前面两篇文章连起来看。 本文用于修改cityscapes数据集的标签颜色与Semankitti数据集的标签一致&#xff0c;对修改后的数据集进行训练。需要下载两个开发工具包和一个数据集&#xff0…

【项目日记(五)】第二层: 中心缓存的具体实现(上)

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:项目日记-高并发内存池⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你做项目   &#x1f51d;&#x1f51d; 开发环境: Visual Studio 2022 项目日…

K8S搭建(centos)十、Dashboard配置(主节点)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

为什么 FPGA 比 CPU 和 GPU 快?

FPGA、GPU 与 CPU——AI 应用的硬件选择 现场可编程门阵列 (FPGA) 为人工智能 (AI) 应用带来许多优势。图形处理单元 (GPU) 和传统中央处理单元 (CPU) 相比如何&#xff1f; 人工智能&#xff08;AI&#xff09;一词是指能够以类似于人类的方式做出决策的非人类机器智能。这包…

秋招实习,刷题网站推荐

codefun2000.com 优点1: 题目全部改编自公司笔试真题&#xff0c;可以做做往年真题练手。 优点2: 该平台和公司笔试模式一样&#xff0c;都是Acm输入输出&#xff0c;更有利于准备秋招。 优点3: 平台主页有博客&#xff0c;以及各大公司真题知识点思维导图&#xff0c;讲…