Mybatis源码学习第七天(插件开发原理)
时间:2022-07-26
本文章向大家介绍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:运行测试用例
本来不打算写的,后来想想写一个吧;
先看一下接口;
1 /**
2 * Copyright 2009-2019 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.apache.ibatis.plugin;
17
18 import java.util.Properties;
19
20 /**
21 * @author Clinton Begin
22 */
23 public interface Interceptor {
24
25 /**
26 * 执行拦截逻辑的方法
27 * @param invocation
28 * @return
29 * @throws Throwable
30 */
31 Object intercept(Invocation invocation) throws Throwable;
32
33 /**
34 *
35 * @param target 被拦截的对象,他的作用就是给拦截的对象生成一个代理对象
36 * @return
37 */
38 default Object plugin(Object target) {
39 return Plugin.wrap(target, this);
40 }
41
42 /**
43 * 读取 在plugin中设置的参数
44 * @param properties
45 */
46 default void setProperties(Properties properties) {
47 // NOP
48 }
49
50 }
手写慢SQL插件拦截器
1 package org.apache.ibatis.plugin.impl;
2
3 import org.apache.ibatis.executor.statement.StatementHandler;
4 import org.apache.ibatis.logging.jdbc.PreparedStatementLogger;
5 import org.apache.ibatis.plugin.Interceptor;
6 import org.apache.ibatis.plugin.Intercepts;
7 import org.apache.ibatis.plugin.Invocation;
8 import org.apache.ibatis.plugin.Signature;
9 import org.apache.ibatis.reflection.MetaObject;
10 import org.apache.ibatis.reflection.SystemMetaObject;
11 import org.apache.ibatis.session.ResultHandler;
12
13 import java.sql.PreparedStatement;
14 import java.sql.Statement;
15 import java.util.Properties;
16
17 /**
18 * @Description 慢SQL查询日志拦截器
19 * @ClassName ThresholdInterceptor
20 * @Author mr.zhang
21 * @Date 2020/3/23 21:35
22 * @Version 1.0.0
23 **/
24
25 /**
26 * 定义拦截位置
27 * 参数解释:
28 * type:拦截的类
29 * method:该类的那个方法
30 * args:该方法的参数
31 */
32 @Intercepts({
33 @Signature(type = StatementHandler.class, method = "query", args = {Statement.class,ResultHandler.class})
34 })
35 public class ThresholdInterceptor implements Interceptor {
36
37 // 时间阈值
38 private Long threshold;
39
40 @Override
41 public Object intercept(Invocation invocation) throws Throwable {
42 long begin = System.currentTimeMillis();
43 Object proceed = invocation.proceed();
44 long end = System.currentTimeMillis();
45 long runTime = end - begin;
46 // 如果大于等于阈值那么记录慢SQL
47 if(runTime>=threshold){
48 // 获取参数
49 Object[] args = invocation.getArgs();
50 // 根据方法参数可得知第0个是Statement
51 Statement stmt = (Statement) args[0];
52 // 通过反射转化为metaObject
53 MetaObject metaObject = SystemMetaObject.forObject(stmt);
54 // getValue("h")是因为在动态代理中存在的InvocationHandler就是h
55 // protected InvocationHandler h; 在Proxy类中定义的 在动态代理生成代理类时都会存在
56 PreparedStatementLogger preparedStatementLogger = (PreparedStatementLogger) metaObject.getValue("h");
57 PreparedStatement preparedStatement = preparedStatementLogger.getPreparedStatement();
58 System.out.println("Sql语句:“"+preparedStatement.toString()+"”执行时间为:"+runTime+"毫秒,已经超过阈值!");
59 }
60
61 return proceed;
62 }
63
64 @Override
65 public void setProperties(Properties properties) {
66 this.threshold = Long.valueOf(properties.getProperty("threshold"));
67 }
68 }
如果需要使用在mybatis-config.xml 的plugins中配置就可以了,记得配置阈值哦;
作者:彼岸舞
时间:2020 323
内容关于:Mybatis
本文部分来源于网络,只做技术分享,一概不负任何责任
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释