插件概述:

插件是用来改变或者扩展mybatis的原有功能,mybatis的插件就是通过继承Interceptor拦截器实现的,在没有完全理解插件之前j禁止使用插件对mybatis进行扩展,有可能会导致严重的问题;

mybatis中能使用插件进行拦截的接口和方法如下:

Executor(update,query,flushStatement,commit,rollback,getTransation,close,isClose);

StatementHandler(prepare,parameterize,batch,update,query);

ParameterHandler(getParameterObject,setParameters);

ResultSetHandler(handleResultSets.handleCursorResultSets,handleOutputParameters);

插件实现步骤:

1:实现Interceptor接口方法

2:确定拦截的签名

3:在配置文件中配置插件

4:运行测试用例

本来不打算写的,后来想想写一个吧;

先看一下接口;

 /**
* Copyright 2009-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.plugin; import java.util.Properties; /**
* @author Clinton Begin
*/
public interface Interceptor { /**
* 执行拦截逻辑的方法
* @param invocation
* @return
* @throws Throwable
*/
Object intercept(Invocation invocation) throws Throwable; /**
*
* @param target 被拦截的对象,他的作用就是给拦截的对象生成一个代理对象
* @return
*/
default Object plugin(Object target) {
return Plugin.wrap(target, this);
} /**
* 读取 在plugin中设置的参数
* @param properties
*/
default void setProperties(Properties properties) {
// NOP
} }

手写慢SQL插件拦截器

 package org.apache.ibatis.plugin.impl;

 import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.logging.jdbc.PreparedStatementLogger;
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.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.session.ResultHandler; import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.Properties; /**
* @Description 慢SQL查询日志拦截器
* @ClassName ThresholdInterceptor
* @Author mr.zhang
* @Date 2020/3/23 21:35
* @Version 1.0.0
**/ /**
* 定义拦截位置
* 参数解释:
* type:拦截的类
* method:该类的那个方法
* args:该方法的参数
*/
@Intercepts({
@Signature(type = StatementHandler.class, method = "query", args = {Statement.class,ResultHandler.class})
})
public class ThresholdInterceptor implements Interceptor { // 时间阈值
private Long threshold; @Override
public Object intercept(Invocation invocation) throws Throwable {
long begin = System.currentTimeMillis();
Object proceed = invocation.proceed();
long end = System.currentTimeMillis();
long runTime = end - begin;
// 如果大于等于阈值那么记录慢SQL
if(runTime>=threshold){
// 获取参数
Object[] args = invocation.getArgs();
// 根据方法参数可得知第0个是Statement
Statement stmt = (Statement) args[0];
// 通过反射转化为metaObject
MetaObject metaObject = SystemMetaObject.forObject(stmt);
// getValue("h")是因为在动态代理中存在的InvocationHandler就是h
// protected InvocationHandler h; 在Proxy类中定义的 在动态代理生成代理类时都会存在
PreparedStatementLogger preparedStatementLogger = (PreparedStatementLogger) metaObject.getValue("h");
PreparedStatement preparedStatement = preparedStatementLogger.getPreparedStatement();
System.out.println("Sql语句:“"+preparedStatement.toString()+"”执行时间为:"+runTime+"毫秒,已经超过阈值!");
} return proceed;
} @Override
public void setProperties(Properties properties) {
this.threshold = Long.valueOf(properties.getProperty("threshold"));
}
}

如果需要使用在mybatis-config.xml 的plugins中配置就可以了,记得配置阈值哦;

作者:彼岸舞

时间:2020\03\23

内容关于:Mybatis

本文部分来源于网络,只做技术分享,一概不负任何责任

Mybatis源码学习第七天(插件开发原理)的更多相关文章

  1. Mybatis源码学习第七天(PageHelper分析)

    其实我本来是不打算写这个PageHelper的,但是后来想了想,还是写了吧!现在市场用Mybatis的产品分页应该差不多都是用PageHelper来实现的,毕竟Mybatis的分页rowbound.. ...

  2. Mybatis源码学习第七天(插件源码分析)

    为了不把开发和源码分析混淆,决定分开写; 接下来分析一下插件的源码,说道这里老套路先说一个设计模式,他就是责任链模式 责任链模式:就是把一件工作分别经过链上的各个节点,让这些节点依次处理这个工作,和装 ...

  3. mybatis源码学习:一级缓存和二级缓存分析

    目录 零.一级缓存和二级缓存的流程 一级缓存总结 二级缓存总结 一.缓存接口Cache及其实现类 二.cache标签解析源码 三.CacheKey缓存项的key 四.二级缓存TransactionCa ...

  4. mybatis源码学习:基于动态代理实现查询全过程

    前文传送门: mybatis源码学习:从SqlSessionFactory到代理对象的生成 mybatis源码学习:一级缓存和二级缓存分析 下面这条语句,将会调用代理对象的方法,并执行查询过程,我们一 ...

  5. mybatis源码学习:插件定义+执行流程责任链

    目录 一.自定义插件流程 二.测试插件 三.源码分析 1.inteceptor在Configuration中的注册 2.基于责任链的设计模式 3.基于动态代理的plugin 4.拦截方法的interc ...

  6. mybatis源码学习(一) 原生mybatis源码学习

    最近这一周,主要在学习mybatis相关的源码,所以记录一下吧,算是一点学习心得 个人觉得,mybatis的源码,大致可以分为两部分,一是原生的mybatis,二是和spring整合之后的mybati ...

  7. Mybatis源码学习第六天(核心流程分析)之Executor分析

    今Executor这个类,Mybatis虽然表面是SqlSession做的增删改查,其实底层统一调用的是Executor这个接口 在这里贴一下Mybatis查询体系结构图 Executor组件分析 E ...

  8. Mybatis源码学习之DataSource(七)_1

    简述 在数据持久层中,数据源是一个非常重要的组件,其性能直接关系到整个数据持久层的性能.在实践中比较常见的第三方数据源组件有Apache Common DBCP.C3P0.Proxool等,MyBat ...

  9. Mybatis源码学习第八天(总结)

    源码学习到这里就要结束了; 来总结一下吧 Mybatis的总体架构 这次源码学习我们,学习了重点的模块,在这里我想说一句,源码的学习不是要所有的都学,一行一行的去学,这是错误的,我们只需要学习核心,专 ...

随机推荐

  1. 【av68676164(p38-p40)】进程调度

    6.1 进程调度概念 进程调度 在合适的时候以一定策略选择一个就绪进程运行 进程调度的目标 响应速度尽可能快 进程处理的时间尽可能短 系统吞吐量尽可能大 资源利用率尽可能高 对所有进程要公平 避免饥饿 ...

  2. 总结笔记 | 深度学习之Pytorch入门教程

    笔记作者:王博Kings 目录 一.整体学习的建议 1.1 如何成为Pytorch大神? 1.2 如何读Github代码? 1.3 代码能力太弱怎么办? 二.Pytorch与TensorFlow概述 ...

  3. JavaFX桌面应用-MVC模式开发,“真香”

    使用mvc模块开发JavaFX桌面应用在JavaFX系列文章第一篇 JavaFX桌面应用开发-HelloWorld 已经提到过,这里单独整理使用mvc模式开发开发的流程. ~ JavaFX桌面应用开发 ...

  4. 总结vue知识体系之实用技巧

    vue 作为目前前端三大框架之一,对于前端开发者可以说是必备技能.那么怎么系统地学习和掌握 vue 呢?为此,我做了简单的知识体系体系总结,不足之处请各位大佬多多包涵和指正,如果喜欢的可以点个小赞!本 ...

  5. 炼技术(9): 简约而不简单,永不停歇的测试 -- always_run

    最强战力,永不停歇的测试:always_run 许多工程师写完程序后,都不愿意对自己的程序做仔细测试. 很多测试说会做自动化测试,可能工作好几年都没真做过多少自动化测试. 我们的解决方案是,在系统的测 ...

  6. jqgrid 获取选中用户的数据插入

    因为查询出的表和被插入的表不是在同一个数据库,所以先从前台jqgrid表格中获取到数据后,再插入表中. 实现: 获取到jqgrid选中 的每行数据之后,发ajax请求把数据以json格式传入后台,后台 ...

  7. 《java多线程——线程简介与其创建(1)》

    Java 给多线程编程提供了内置的支持. 一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. 多线程是多任务的一种特别的形式,但多线程使用了更小的资源开 ...

  8. Docker商业版受限,胖容器是个选择

    前情概要 8月13日,Docker 公司更新了网站服务协议,条款申明,禁止禁运国家和被列入「美国实体清单」的组织和个人使用带有该服务协议链接的 Docker 网站和所有相关网站.这一更新协议迅速引起了 ...

  9. Windows server 2008 搭建DNS服务

    现在用Windows搭建DNS的已经很少了,感觉也只有一些公司的某块部分能用上,最近在捣鼓这个,索性直接写下来,以后可以看了直接用. 开始: ★★★配置静态IP地址 老样子,有关服务器功能的建立,都是 ...

  10. 服务应用突然宕机了?别怕,Dubbo 帮你自动搞定服务隔离!

    某日中午,午睡正香的时候,接到系统的报警电话,提示生产某物理机异常宕机了,目前该物理机已恢复,需要重启上面部署的应用. 这时瞬间没有了睡意,登上堡垒机,快速重启了应用,系统恢复正常.本想着继续午睡,但 ...