1、plugins

MyBatis官网对于plugins的描述是这样的:

MyBatis allows you to intercept calls to at certain points within the execution of a mapped statement. By default, MyBatis allows plug-ins to intercept method calls of:

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)
  • StatementHandler (prepare, parameterize, batch, update, query)

The details of these classes methods can be discovered by looking at the full method signature of each, and the source code which is available with each MyBatis release. You should understand the behaviour of the method you’re overriding, assuming you’re doing something more than just monitoring calls. If you attempt to modify or override the behaviour of a given method, you’re likely to break the core of MyBatis. These are low level classes and methods, so use plug-ins with caution.

Using plug-ins is pretty simple given the power they provide. Simply implement the Interceptor interface, being sure to specify the signatures you want to intercept.

// ExamplePlugin.java
@Intercepts({@Signature(
type= Executor.class,
method = "update",
args = {MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
return invocation.proceed();
}
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
}
}
<!-- mybatis-config.xml -->
<plugins>
<plugin interceptor="org.mybatis.example.ExamplePlugin">
<property name="someProperty" value="100"/>
</plugin>
</plugins>

The plug-in above will intercept all calls to the "update" method on the Executor instance, which is an internal object responsible for the low level execution of mapped statements.

NOTE Overriding the Configuration Class

In addition to modifying core MyBatis behaviour with plugins, you can also override the Configuration class entirely. Simply extend it and override any methods inside, and pass it into the call to the SqlSessionFactoryBuilder.build(myConfig) method. Again though, this could have a severe impact on the behaviour of MyBatis, so use caution.

2、定义一个Interceptor

 package com.cjs.boot.interceptor;

 import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler; import java.sql.Statement;
import java.util.Properties; @Slf4j
@Intercepts({@Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class})})
public class SqlStatementInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
long startTime = System.currentTimeMillis();
try {
return invocation.proceed();
} finally {
long endTime = System.currentTimeMillis(); StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
BoundSql boundSql = statementHandler.getBoundSql();
String sql = boundSql.getSql();
sql = sql.replace("\n", "").replace("\t", "").replaceAll("\\s+", " "); log.info("执行SQL: [{}]花费{}ms", sql, (endTime - startTime)); }
} @Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
} @Override
public void setProperties(Properties properties) { }
}

2、配置SqlSessionFactory

 package com.cjs.boot.config;

 import com.cjs.boot.interceptor.SqlStatementInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import javax.annotation.Resource;
import javax.sql.DataSource; @Configuration
public class MyBatisConfig { @Resource
private DataSource dataSource; @Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setPlugins(new Interceptor[]{new SqlStatementInterceptor()});
PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(pathMatchingResourcePatternResolver.getResources("classpath:mapper/*Mapper.xml"));
sqlSessionFactoryBean.setTypeAliasesPackage("com.cjs.boot.domain.entity");
return sqlSessionFactoryBean.getObject();
} }

3、运行效果

2018-05-09 13:53:55.589 DEBUG 10988 --- [nio-8080-exec-2] c.c.b.m.C.selectByMerchantId             : ==>  Preparing: SELECT id, merchant_id, coupon_name, coupon_type, par_value, quantity, release_start_time, release_end_time, limit_type, limit_num, remark, create_time, update_time, yn FROM coupon_info WHERE merchant_id = ?
2018-05-09 13:53:55.605 DEBUG 10988 --- [nio-8080-exec-2] c.c.b.m.C.selectByMerchantId : ==> Parameters: 10009(Integer)
2018-05-09 13:53:55.619 DEBUG 10988 --- [nio-8080-exec-2] c.c.b.m.C.selectByMerchantId : <== Total: 0
2018-05-09 13:53:55.620 INFO 10988 --- [nio-8080-exec-2] c.c.b.i.SqlStatementInterceptor : 执行SQL: [SELECT id, merchant_id, coupon_name, coupon_type, par_value, quantity, release_start_time, release_end_time, limit_type, limit_num, remark, create_time, update_time, yn FROM coupon_info WHERE merchant_id = ?]花费15ms

4、补充

4.1、@Signature注解的那几个参数该怎么写

前面文档中说了,可以拦截那四个接口。本例中,我只想拦截查询的SQL,所以我选择拦截StatementHandler的query方法

package org.apache.ibatis.executor.statement;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.session.ResultHandler; public interface StatementHandler {
Statement prepare(Connection var1, Integer var2) throws SQLException; void parameterize(Statement var1) throws SQLException; void batch(Statement var1) throws SQLException; int update(Statement var1) throws SQLException; <E> List<E> query(Statement var1, ResultHandler var2) throws SQLException; <E> Cursor<E> queryCursor(Statement var1) throws SQLException; BoundSql getBoundSql(); ParameterHandler getParameterHandler();
}

所以,@Signature注解中,type表示拦截的接口,method表示接口中的方法,而参数就是该方法的参数

4.2、截图

MyBatis打印SQL执行时间的更多相关文章

  1. mybatis 打印sql 语句

    拦截器 package com.cares.asis.mybatis.interceptor; import java.text.DateFormat; import java.util.Date; ...

  2. mybatis 打印sql log配置

    mybatis 打印sql log, 方便调试.如何配置呢? log4j.xml : <!-- 打印sql start --> <appender name="IBatis ...

  3. 【spring boot】【mybatis】spring boot中mybatis打印sql语句

    spring boot中mybatis打印sql语句,怎么打印出来?[参考:https://www.cnblogs.com/sxdcgaq8080/p/9100178.html] 在applicati ...

  4. 【记录】spring/springboot 配置mybatis打印sql

    ======================springboot mybatis 打印sql========================================== 方式 一: ##### ...

  5. mybatis 打印 sql

    该文中使用的log框架为logback myBatis3.0.6左右的版本时 打印sql的时候只需要配置如下属性: <logger name="java.sql.Connection& ...

  6. (后端)SpringBoot中Mybatis打印sql(转)

    原文地址:https://www.cnblogs.com/expiator/p/8664977.html 如果使用的是application.properties文件,加入如下配置: logging. ...

  7. SpringBoot中Mybatis打印sql

    原文:https://www.cnblogs.com/expiator/p/8664977.html 如果使用的是application.properties文件,加入如下配置: logging.le ...

  8. mybatis 打印SQL

    如果使用的是application.properties文件,加入如下配置: #打印SQL logging.level.com.jn.ssr.supererscuereporting.dao=debu ...

  9. logback mybatis 打印sql语句

    logbac.xml 文件的基础配置参考的园友的 http://www.cnblogs.com/yuanermen/archive/2012/02/13/2349609.html 然后hibernat ...

随机推荐

  1. sed-加速你在Linux的文件编辑

    1. Sed简介 sed是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为"模式空间"(pattern space),接着用sed命令处理缓冲区中 ...

  2. mysql的基本使用命令

    启动:net start mySql; 进入:mysql -u root -p/mysql -h localhost -u root -p databaseName; 列出数据库:show datab ...

  3. 【一天一道LeetCode】#76. Minimum Window Substring

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...

  4. AJAX+jQuery+ASP实现实时验证身份证信息是否已存在---人事系统

    很多时候在网站上注册时,我们会发现,注册表单通常需要检查用户名和电子邮件地址的可用性:从而确保用户之间不拥有相同的用户名和电子邮件地址:一些网站喜欢在用户提交填写的用户信息时,做信息可用性的检查,而一 ...

  5. C++ Primer 有感(复制控制)

    1.不管类是否定义了自己的析构函数,编译器都 自动执行类中非static数据成员的析构函数. 2.如果我们没有定义复制构造函数,编译器就会为我们合成一个.合成复制构造函数的行为是,执行逐个成员初始化, ...

  6. 【Unity Shaders】Diffuse Shading——在Surface Shader中使用properties

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  7. 016-类与对象-OC笔记

    学习目标 1.[理解]对象在内存中的存储 2.[理解]nil和NULL 3.[了解]#pragma mark分组导航标记 4.[理解]方法与函数 5.[掌握]多文件开发 6.[掌握]对象和方法 7.[ ...

  8. Mahout 系列之----共轭梯度

    无预处理共轭梯度 要求解线性方程组 ,稳定双共轭梯度法从初始解 开始按以下步骤迭代: 任意选择向量 使得 ,例如, 对 若 足够精确则退出 预处理共轭梯度 预处理通常被用来加速迭代方法的收敛.要使用预 ...

  9. gc实例与gc报告的阅读

    gc报告的阅读 首先我们看一条gc报告 D:\杂项\java>java -verbose:gc -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails -XX:+ ...

  10. STL算法设计理念 - 预定义函数对象

    预定义函数对象基本概念:标准模板库STL提前定义了很多预定义函数对象 1)使用预定义函数对象: #include <iostream> #include <cstdio> #i ...