Mybatis源码学习第七天(插件开发原理)
插件概述:
插件是用来改变或者扩展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源码学习第七天(插件开发原理)的更多相关文章
- Mybatis源码学习第七天(PageHelper分析)
其实我本来是不打算写这个PageHelper的,但是后来想了想,还是写了吧!现在市场用Mybatis的产品分页应该差不多都是用PageHelper来实现的,毕竟Mybatis的分页rowbound.. ...
- Mybatis源码学习第七天(插件源码分析)
为了不把开发和源码分析混淆,决定分开写; 接下来分析一下插件的源码,说道这里老套路先说一个设计模式,他就是责任链模式 责任链模式:就是把一件工作分别经过链上的各个节点,让这些节点依次处理这个工作,和装 ...
- mybatis源码学习:一级缓存和二级缓存分析
目录 零.一级缓存和二级缓存的流程 一级缓存总结 二级缓存总结 一.缓存接口Cache及其实现类 二.cache标签解析源码 三.CacheKey缓存项的key 四.二级缓存TransactionCa ...
- mybatis源码学习:基于动态代理实现查询全过程
前文传送门: mybatis源码学习:从SqlSessionFactory到代理对象的生成 mybatis源码学习:一级缓存和二级缓存分析 下面这条语句,将会调用代理对象的方法,并执行查询过程,我们一 ...
- mybatis源码学习:插件定义+执行流程责任链
目录 一.自定义插件流程 二.测试插件 三.源码分析 1.inteceptor在Configuration中的注册 2.基于责任链的设计模式 3.基于动态代理的plugin 4.拦截方法的interc ...
- mybatis源码学习(一) 原生mybatis源码学习
最近这一周,主要在学习mybatis相关的源码,所以记录一下吧,算是一点学习心得 个人觉得,mybatis的源码,大致可以分为两部分,一是原生的mybatis,二是和spring整合之后的mybati ...
- Mybatis源码学习第六天(核心流程分析)之Executor分析
今Executor这个类,Mybatis虽然表面是SqlSession做的增删改查,其实底层统一调用的是Executor这个接口 在这里贴一下Mybatis查询体系结构图 Executor组件分析 E ...
- Mybatis源码学习之DataSource(七)_1
简述 在数据持久层中,数据源是一个非常重要的组件,其性能直接关系到整个数据持久层的性能.在实践中比较常见的第三方数据源组件有Apache Common DBCP.C3P0.Proxool等,MyBat ...
- Mybatis源码学习第八天(总结)
源码学习到这里就要结束了; 来总结一下吧 Mybatis的总体架构 这次源码学习我们,学习了重点的模块,在这里我想说一句,源码的学习不是要所有的都学,一行一行的去学,这是错误的,我们只需要学习核心,专 ...
随机推荐
- 曲线生成与求交—B样条曲线
B样条曲线生成 Bezier曲线缺点:改变任一控制点的位置,将影响整条曲线的形状. B样条曲线是对Bezier曲线的改进,可进行局部控制,生成的曲线与控制多边形的外形更接近,将Bezier曲线作为一特 ...
- Navicat Premium 安装破解
软件官网 : https://www.navicat.com.cn/ Navicat Premium 12 下载地址:https://www.lanzous.com/i9j0syf 密码:7pup N ...
- java web 下载文件 response.setHeader()的用法 (转载)
response.setHeader()的用法 response.setHeader()下载中文文件名乱码问题 收藏 1. HTTP消息头 (1)通用信息头 即能用于请求消息中,也能用于响应信息中,但 ...
- C#LeetCode刷题之#344-反转字符串(Reverse String)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3933 访问. 编写一个函数,其作用是将输入的字符串反转过来. 输 ...
- C#LeetCode刷题之#121-买卖股票的最佳时机(Best Time to Buy and Sell Stock)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4014 访问. 给定一个数组,它的第 i 个元素是一支给定股票第 ...
- Sublime Text 3关闭更新新版本的提醒
1 关闭更新提示前首先需要 输入激活码,下边是我的,亲测有效,无效的话,自行百度填写. ----- BEGIN LICENSE ----- ZYNGA INC. 50 User License EA7 ...
- Android 本地缓存Acache的简单使用
设置缓存数据: ACache mCache = ACache.get(this); mCache.put("key1", "value"); //保存6秒,如果 ...
- Collections.synchronizedMap()与ConcurrentHashMap区别
Collections.synchronizedMap()与ConcurrentHashMap主要区别是:Collections.synchronizedMap()和Hashtable一样,实现上在调 ...
- 4.oracle sql*plus常用命令
一.sys用户和system用户Oracle安装会自动的生成sys用户和system用户(1).sys用户是超级用户,具有最高权限,具有sysdba角色,有create database的权限,该用户 ...
- 企业项目实战 .Net Core + Vue/Angular 分库分表日志系统四 | 强化设计方案
教程预览 01 | 前言 02 | 简单的分库分表设计 03 | 控制反转搭配简单业务 04 | 强化设计方案 强化 先来记录一下我们现在的样子,一会好做个对比 1.在EasyLogger.DbSto ...