优雅的利用Mybatis插件实现sql查询耗时统计

一. Mybatis反射机制讲解

二. 代理模式讲解

  1. 静态代理

  2. 动态代理

    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查询耗时统计相关推荐

  1. 利用MyBatis的动态SQL特性抽象统一SQL查询接口

    1. SQL查询的统一抽象 MyBatis制动动态SQL的构造,利用动态SQL和自定义的参数Bean抽象,可以将绝大部分SQL查询抽象为一个统一接口,查询参数使用一个自定义bean继承Map,使用映射 ...

  2. java批量执行查询sql语句_详解MyBatis直接执行SQL查询及数据批量插入

    一.直接执行SQL查询: 1.mappers文件节选 ${paramSQL} 2.DAO类节选 public interface SomeDAO{ List getInstanceModel(@Par ...

  3. SpringCloud或SpringBoot+Mybatis-Plus利用mybatis插件实现数据操作记录及更新对比

    引文 本文主要介绍如何使用mybatis插件实现拦截数据库操作并根据不同需求进行数据对比分析,主要适用于系统中需要对数据操作进行记录.在更新数据时准确记录更新字段 核心:mybatis插件(拦截器). ...

  4. MyBatis直接执行SQL查询及批量插入数据

    转:http://www.cnblogs.com/mabaishui/archive/2012/06/20/2556500.html 一.直接执行SQL查询: 1.mappers文件节选 <re ...

  5. Mybatis——注入执行sql查询、更新、新增以及建表语句

    文章目录 前言 案例 dao和mapper编写 XXXmapper.xml编写 编写业务层代码,进行注入调用 额外扩展--创建表语句 前言 在平时的项目开发中,mybatis应用非常广泛,但一般都是直 ...

  6. 第 3-2 课:SpringBoot如何优雅地使⽤ MyBatis XML 配置版

    MyBatis 是现如今最流⾏的 ORM 框架之⼀,我们先来了解⼀下什么是 ORM 框架. ORM 框架 对象关系映射(Object Relational Mapping,ORM)模式是⼀种为了解决⾯ ...

  7. Solr实现SQL的查询与统计--转载

    原文地址:http://shiyanjun.cn/archives/78.html Cloudera公司已经推出了基于Hadoop平台的查询统计分析工具Impala,只要熟悉SQL,就可以熟练地使用I ...

  8. MyBatis原理分析之四:一次SQL查询的源码分析

    上回我们讲到Mybatis加载相关的配置文件进行初始化,这回我们讲一下一次SQL查询怎么进行的. 准备工作 Mybatis完成一次SQL查询需要使用的代码如下: Java代码   String res ...

  9. java中sql语句怎么把开始和结束时间作为参数写sql查询_java程序员跳槽的一道坎,大公司面试官都会问的Mybatis...

    一.什么是Mybatis? 1. Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动.创建连接.创建statement ...

最新文章

  1. 数据预处理-异常值识别
  2. 清结算系统的一些思考
  3. Win64 驱动内核编程-13.回调监控模块加载
  4. TensorFlow——多维矩阵的转置(transpose)
  5. Android多种View动画:EasyAndroidAnimations
  6. Ubuntu 12.04 LTS安装VMware Tools:无法找到kernel header path的问题
  7. Python基础项目实践之:学生信息管理系统
  8. linux64bit安装mysql、jdk、nodejs、nginx笔记
  9. Microsoft Azure Remoteapp使用自定义镜像创建桌面服务
  10. 苹果iPhone 12系列智能手机支持北斗卫星导航定位
  11. C++ Qt全局异常处理器_异常处理
  12. 向“3+1” SQLServer2008集群增加磁盘
  13. BZOJ 3531[Sdoi2014]旅行
  14. 鸡啄米VS2010/MFC编程入门教程——学习3(安装VS2010)
  15. php3d建模,3d建模师容易找工作吗
  16. 网络攻防之wireshark抓取登录信息
  17. YOLOv5损失函数定义
  18. oracle pq distribute,详解Oracle hints PQ_DISTRIBUTE
  19. C1任务01-修改《植物大战僵尸》游戏存档
  20. 你知道怎么衡量硬件设备的算力吗?

热门文章

  1. 海量过程数据的 CPK 与 PPK 计算
  2. esp8266 OLED SSD1306程序集合
  3. 第十一届“泰迪杯”数据挖掘挑战赛赛前指导安排
  4. mysql测试数据库 jmeter_第三篇--Jmeter测试数据库Mysql
  5. cmd命令之Xcopy介绍_复制文件夹里所有文件到另一个文件夹操作方式
  6. python使用ddt_python中,ddt模块的使用
  7. 虚拟机VMware tools安装【转载】
  8. 垃圾邮件检测_如何在您的电子邮件中检测垃圾邮件
  9. Java国际化ResourceBundle详解
  10. 软件安全测试-软件安全测试概述