优雅的利用Mybatis插件实现sql查询耗时统计
优雅的利用Mybatis插件实现sql查询耗时统计
一. Mybatis反射机制讲解
二. 代理模式讲解
静态代理
动态代理
JDK动态代理参考代码
Proxy.newProxyInstance(xxx.getClass().getClassLoader(),new Class[]{Interface.class},new InvocationHandler(){public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("1.买材料");System.out.println("2.找工人");System.out.println("3.开始装修");Object invoke = method.invoke(target, args);System.out.println("4.后期服务");return invoke;}});
三、mybatis自定义插件实现
@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})}
)
public class SqlExecuteTimeStatisticPlugin implements Interceptor {}
四、mybatis自定义插件原理
在mybatis的 Configuration
类中有如下4个方法中声明了插件启动的逻辑
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {ParameterHandler parameterHandler mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);// 插件应用核心代码parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);return parameterHandler;}public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler,ResultHandler resultHandler, BoundSql boundSql) {ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);// 插件应用核心代码resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);return resultSetHandler;}
public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds,resultHandler, boundSql);// 插件应用核心代码statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);return statementHandler;}public Executor newExecutor(Transaction transaction, ExecutorType executorType) {executorType = executorType == null ? defaultExecutorType : executorType;executorType = executorType == null ? ExecutorType.SIMPLE : executorType;Executor executor;if (ExecutorType.BATCH == executorType) {executor = new BatchExecutor(this, transaction);} else if (ExecutorType.REUSE == executorType) {executor = new ReuseExecutor(this, transaction);} else {executor = new SimpleExecutor(this, transaction);}if (cacheEnabled) {executor = new CachingExecutor(executor);}// 插件应用核心代码executor = (Executor) interceptorChain.pluginAll(executor);return executor;}
插件原理在myttis的Plugin.wrap(target, this)
核心方法
public class Plugin implements InvocationHandler{// wrap 方式实现jdk动态代理逻辑,产生代理类public static Object wrap(Object target, Interceptor interceptor) {Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);Class<?> type = target.getClass();Class<?>[] interfaces = getAllInterfaces(type, signatureMap);if (interfaces.length > 0) {// 声明动态代理,进行方法拦截return Proxy.newProxyInstance(type.getClassLoader(),interfaces,new Plugin(target, interceptor, signatureMap));}return target;}/// jdk动态代理默认执行方法public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {try {Set<Method> methods = signatureMap.get(method.getDeclaringClass());if (methods != null && methods.contains(method)) {return interceptor.intercept(new Invocation(target, method, args));}return method.invoke(target, args);} catch (Exception e) {throw ExceptionUtil.unwrapThrowable(e);}}}
优雅的利用Mybatis插件实现sql查询耗时统计相关推荐
- 利用MyBatis的动态SQL特性抽象统一SQL查询接口
1. SQL查询的统一抽象 MyBatis制动动态SQL的构造,利用动态SQL和自定义的参数Bean抽象,可以将绝大部分SQL查询抽象为一个统一接口,查询参数使用一个自定义bean继承Map,使用映射 ...
- java批量执行查询sql语句_详解MyBatis直接执行SQL查询及数据批量插入
一.直接执行SQL查询: 1.mappers文件节选 ${paramSQL} 2.DAO类节选 public interface SomeDAO{ List getInstanceModel(@Par ...
- SpringCloud或SpringBoot+Mybatis-Plus利用mybatis插件实现数据操作记录及更新对比
引文 本文主要介绍如何使用mybatis插件实现拦截数据库操作并根据不同需求进行数据对比分析,主要适用于系统中需要对数据操作进行记录.在更新数据时准确记录更新字段 核心:mybatis插件(拦截器). ...
- MyBatis直接执行SQL查询及批量插入数据
转:http://www.cnblogs.com/mabaishui/archive/2012/06/20/2556500.html 一.直接执行SQL查询: 1.mappers文件节选 <re ...
- Mybatis——注入执行sql查询、更新、新增以及建表语句
文章目录 前言 案例 dao和mapper编写 XXXmapper.xml编写 编写业务层代码,进行注入调用 额外扩展--创建表语句 前言 在平时的项目开发中,mybatis应用非常广泛,但一般都是直 ...
- 第 3-2 课:SpringBoot如何优雅地使⽤ MyBatis XML 配置版
MyBatis 是现如今最流⾏的 ORM 框架之⼀,我们先来了解⼀下什么是 ORM 框架. ORM 框架 对象关系映射(Object Relational Mapping,ORM)模式是⼀种为了解决⾯ ...
- Solr实现SQL的查询与统计--转载
原文地址:http://shiyanjun.cn/archives/78.html Cloudera公司已经推出了基于Hadoop平台的查询统计分析工具Impala,只要熟悉SQL,就可以熟练地使用I ...
- MyBatis原理分析之四:一次SQL查询的源码分析
上回我们讲到Mybatis加载相关的配置文件进行初始化,这回我们讲一下一次SQL查询怎么进行的. 准备工作 Mybatis完成一次SQL查询需要使用的代码如下: Java代码 String res ...
- java中sql语句怎么把开始和结束时间作为参数写sql查询_java程序员跳槽的一道坎,大公司面试官都会问的Mybatis...
一.什么是Mybatis? 1. Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动.创建连接.创建statement ...
最新文章
- 数据预处理-异常值识别
- 清结算系统的一些思考
- Win64 驱动内核编程-13.回调监控模块加载
- TensorFlow——多维矩阵的转置(transpose)
- Android多种View动画:EasyAndroidAnimations
- Ubuntu 12.04 LTS安装VMware Tools:无法找到kernel header path的问题
- Python基础项目实践之:学生信息管理系统
- linux64bit安装mysql、jdk、nodejs、nginx笔记
- Microsoft Azure Remoteapp使用自定义镜像创建桌面服务
- 苹果iPhone 12系列智能手机支持北斗卫星导航定位
- C++ Qt全局异常处理器_异常处理
- 向“3+1” SQLServer2008集群增加磁盘
- BZOJ 3531[Sdoi2014]旅行
- 鸡啄米VS2010/MFC编程入门教程——学习3(安装VS2010)
- php3d建模,3d建模师容易找工作吗
- 网络攻防之wireshark抓取登录信息
- YOLOv5损失函数定义
- oracle pq distribute,详解Oracle hints PQ_DISTRIBUTE
- C1任务01-修改《植物大战僵尸》游戏存档
- 你知道怎么衡量硬件设备的算力吗?
热门文章
- 海量过程数据的 CPK 与 PPK 计算
- esp8266 OLED SSD1306程序集合
- 第十一届“泰迪杯”数据挖掘挑战赛赛前指导安排
- mysql测试数据库 jmeter_第三篇--Jmeter测试数据库Mysql
- cmd命令之Xcopy介绍_复制文件夹里所有文件到另一个文件夹操作方式
- python使用ddt_python中,ddt模块的使用
- 虚拟机VMware tools安装【转载】
- 垃圾邮件检测_如何在您的电子邮件中检测垃圾邮件
- Java国际化ResourceBundle详解
- 软件安全测试-软件安全测试概述