MyBatis打印SQL执行时间

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

 1 package com.cjs.boot.interceptor;
 2
 3 import lombok.extern.slf4j.Slf4j;
 4 import org.apache.ibatis.executor.statement.StatementHandler;
 5 import org.apache.ibatis.mapping.BoundSql;
 6 import org.apache.ibatis.plugin.*;
 7 import org.apache.ibatis.session.ResultHandler;
 8
 9 import java.sql.Statement;
10 import java.util.Properties;
11
12 @Slf4j
13 @Intercepts({@Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class})})
14 public class SqlStatementInterceptor implements Interceptor {
15     @Override
16     public Object intercept(Invocation invocation) throws Throwable {
17         long startTime = System.currentTimeMillis();
18         try {
19             return invocation.proceed();
20         } finally {
21             long endTime = System.currentTimeMillis();
22
23             StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
24             BoundSql boundSql = statementHandler.getBoundSql();
25             String sql = boundSql.getSql();
26             sql = sql.replace("\n", "").replace("\t", "").replaceAll("\\s+", " ");
27
28             log.info("执行SQL: [{}]花费{}ms", sql, (endTime - startTime));
29
30         }
31     }
32
33     @Override
34     public Object plugin(Object target) {
35         return Plugin.wrap(target, this);
36     }
37
38     @Override
39     public void setProperties(Properties properties) {
40
41     }
42 }

2、配置SqlSessionFactory

 1 package com.cjs.boot.config;
 2
 3 import com.cjs.boot.interceptor.SqlStatementInterceptor;
 4 import org.apache.ibatis.plugin.Interceptor;
 5 import org.apache.ibatis.session.SqlSessionFactory;
 6 import org.mybatis.spring.SqlSessionFactoryBean;
 7 import org.springframework.context.annotation.Bean;
 8 import org.springframework.context.annotation.Configuration;
 9 import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
10
11 import javax.annotation.Resource;
12 import javax.sql.DataSource;
13
14 @Configuration
15 public class MyBatisConfig {
16
17     @Resource
18     private DataSource dataSource;
19
20     @Bean
21     public SqlSessionFactory sqlSessionFactory() throws Exception {
22         SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
23         sqlSessionFactoryBean.setDataSource(dataSource);
24         sqlSessionFactoryBean.setPlugins(new Interceptor[]{new SqlStatementInterceptor()});
25         PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
26         sqlSessionFactoryBean.setMapperLocations(pathMatchingResourcePatternResolver.getResources("classpath:mapper/*Mapper.xml"));
27         sqlSessionFactoryBean.setTypeAliasesPackage("com.cjs.boot.domain.entity");
28         return sqlSessionFactoryBean.getObject();
29     }
30
31 }

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、截图

原文地址:https://www.cnblogs.com/mrchenzheng/p/12165654.html

时间: 2024-11-05 00:47:44

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

mybatis 打印sql log配置

mybatis 打印sql log, 方便调试.如何配置呢? log4j.xml : <!-- 打印sql start --> <appender name="IBatis" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="Conversi

Java实战之路(1):SpringBoot项目中使用Mybatis打印Sql语句

SpringBoot项目中使用Mybatis打印Sql语句 如题,实际项目中使用很多都会用到SpringBoot+Mybatis的经典搭配进行开发,数据库里明明有数据,可是程序运行就是查不到,此时我们在本地Debug时,需要将Mybatis的实际Sql打印出来,看看Sql与我们期望的是否一致,或者将Sql拿到数据库中直接执行,看看结果.这里简单介绍几种实战中的用法. 方法一 properties:在application.properties配置文件中增加如下配置 logging.level.c

logback mybatis 打印sql语句

logbac.xml 文件的基础配置参考的园友的 http://www.cnblogs.com/yuanermen/archive/2012/02/13/2349609.html 然后hibernate 和 jpa 相关的sql能够打印.后来整合mybatis发现不能打印sql.后参考 http://clojure.iteye.com/blog/2031318 的评论发现了网友提示 照你说的配置后,仍不能显示sql.倒是看了这个后,成功了.http://stackoverflow.com/que

mybatis 打印 sql

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

SpringBoot中Mybatis打印sql(转)

原文地址:https://www.cnblogs.com/expiator/p/8664977.html 如果使用的是application.properties文件,加入如下配置: logging.level.com.example.demo.dao=debug logging.level.com,后面的路径指的是mybatis对应的方法接口所在的包.并不是mapper.xml所在的包. 如果使用的是application.xml文件,加入如下配置: # 打印sql logging: leve

SpringBoot中Mybatis打印sql

原文:https://www.cnblogs.com/expiator/p/8664977.html 如果使用的是application.properties文件,加入如下配置: logging.level.com.example.demo.dao=debug logging.level.com,后面的路径指的是mybatis对应的方法接口所在的包.并不是mapper.xml所在的包. 如果使用的是application.yml文件,加入如下配置: # 打印sql logging: level:

Mybatis打印SQL

配置mybatis日志级别,打印SQL 1.方案一:配置日志级别 logging.level.org.springboot.demo.mapper=debug 其中org.springboot.demo.mapper目录是项目的mybatis接口包所在路径 这里配置的是springboot的配置文件,如果不是用spring boot构建项目,需要在具体的日志组件下配置 2.方案二:修改mybatis配置文件 在mybatis的全局配置文件中添加如下配置 <setting name="log

mybatis 打印SQL语句

在log4j文件中配置 log4j.rootLogger=DEBUG log4j.logger.com.ibatis=DEBUG log4j.logger.org.mybatis=DEBUG  

mybatis打印sql日志配置

<settings> <!-- 打印查询语句 --> <setting name="logImpl" value="STDOUT_LOGGING" /> </settings> LOG4J2,STDOUT_LOGGING,SLF4J,LOG4J,...