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的总体架构 这次源码学习我们,学习了重点的模块,在这里我想说一句,源码的学习不是要所有的都学,一行一行的去学,这是错误的,我们只需要学习核心,专 ...
随机推荐
- C++实现二叉树的链接存储结构(先根、中根和后根遍历)
验证二叉树的链接存储结构及其上的基本操作. [实验要求]: 1. 从文件创建一棵二叉树,并对其初始化: 2. 先根.中根.后根遍历二叉树: 3. 在二叉树中搜索给定结点的父结点: 4. 搜索二叉树中符 ...
- canvas图片编辑操作:缩放、移动、保存(PC端+移动端)
最近在写canvas关于图片的操作,看了网上的代码基本都是不行的,于是就自己写了一个. html代码 <canvas id="myCanvas" width="37 ...
- C#LeetCode刷题之#206-反转链表(Reverse Linked List)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3828 访问. 反转一个单链表. 输入: 1->2-> ...
- 通过http、https域名访问静态网页、nginx配置负载均衡(nginx配置)
很多场景下需要可以通过浏览器访问静态网页,不想把服务器ip地址直接暴露出来,通过nginx可以解决这个问题. 实现http域名访问静态网页 1.域名解析配置(本文都是以阿里云为例,其他平台,操作步骤类 ...
- 学习java的第五周
java流程控制 顺序结构 语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执的处理步骤组成的,它是任何-一个算法都离不开的一种基本算法结构. 选择结构 if结构 if(布尔表达式 ...
- 【算法•日更•第三十九期】迭代加深搜索:洛谷SP7579 YOKOF - Power Calculus 题解
废话不多说,直接上题: SP7579 YOKOF - Power Calculus 题意翻译 (略过没有营养的题干) 题目大意: 给出正整数n,若只能使用乘法或除法,输出使x经过运算(自己乘或除自己, ...
- centos7下的redis集群模式
1.先安装好单机版的redis 2.Reids安装包里有个集群工具,要复制到/usr/local/bin里去 cd /home/redis/redis-4.0./src ls - cp redis-t ...
- Apache Cassandra 4.0新特性介绍
引言 大家好,我是蔡一凡,是Cassandra的贡献者之一.(虽然我不便透露我的公司名称),但目前我们公司Cassandra的部署是全世界最大的之一,Cassandra在我们公司也有很多的应用. Ca ...
- linux 使用 FIO 测试磁盘的iops
原文链接:https://www.iteye.com/blog/elf8848-2168876 一,FIO安装wget http://brick.kernel.dk/snaps/fio-2.2.5.t ...
- 仿京东BOE官网 JavaScript代码
let items = document.getElementsByClassName('item'); let points = document.getElementsByClassName('p ...