MyBatis的拦截器可以用于在以下对象及方法中拦截修改:

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

每一个方法会对应不同的参数列表, 这些需要体现在Intercepts的Signature中

配置

除了实现Interceptor接口以外, 需要在项目中做以下配置

application.yml

增加对应的mybatis-config.xml, 因为现在还不支持在yml中配置plugin

mybatis:
type-aliases-package: com.compayn.proj.commons.api.dto
mapper-locations: classpath:mapper/*.xml
config-location: classpath:mybatis-config.xml

mybatis-config.xml

增加mybatis配置文件, 注意这里配置的拦截器, 其实际执行顺序是自下而上的

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration>
<settings>
<setting name="..." value="true" />
</settings> <plugins>
<!-- The invocation order is bottom up -->
<plugin interceptor="com.company.proj.commons.impl.interceptor.BaseInterceptor" />
</plugins> </configuration>

  

Interceptor实现

一个简单的拦截器实现, 可以输出执行的sql, 以及执行时间.

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.sql.Statement;
import java.util.Properties; @Intercepts({
@Signature(type = StatementHandler.class, method = "batch", args = { Statement.class}),
@Signature(type = StatementHandler.class, method = "update", args = { Statement.class}),
@Signature(type = StatementHandler.class, method = "query", args = { Statement.class, ResultHandler.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class,Object.class})})
public class BaseInterceptor implements Interceptor {
private static Logger logger = LoggerFactory.getLogger(BaseInterceptor.class); /**
* 用于封装目标对象, 可以返回目标对象本身也可以返回一个它的代理, 这将决定是否会进行拦截
*/
@Override
public Object plugin(Object target) {
if (target instanceof Executor) { // 仅当对象为Executor时, 才使用本插件
return Plugin.wrap(target, this);
} else {
return target;
}
} /**
* 用于配置本插件的相关属性
*/
@Override
public void setProperties(Properties properties) {
// Do nothing
} @Override
public Object intercept(Invocation invocation) throws Throwable {
long start = System.currentTimeMillis(); Object target = invocation.getTarget(); //被代理对象 if (target instanceof Executor) {
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
Object parameter = invocation.getArgs()[1];
BoundSql boundSql = mappedStatement.getBoundSql(parameter);
String sql = boundSql.getSql();
logger.info("SQL: {}", sql);
} Object result = invocation.proceed();
long duration = System.currentTimeMillis() - start;
logger.info("Time elapsed: {}ms", duration);
return result;
}
}

代码说明

@Intercepts 注解: 这个地方配置需要拦截的对象方法, 每个方法对应一个Signature, 这个Signature由对象类型, 方法名和参数组成, 方法名和参数可以直接参考这个对象的接口.

Object plugin(Object target)接口: 用于封装目标对象, 可以返回目标对象本身也可以返回一个它的代理, 这将决定是否会进行拦截

void setProperties(Properties properties)接口: 用于配置本插件的相关属性, 值可以通过Mybatis配置文件传入

Object intercept(Invocation invocation) throws Throwable接口: 执行拦截的方法, 其中 invocation.getTarget() 可以看到实际被代理的对象, 根据对象类型不同, 可以读取这个对象方法的参数并进行需要的操作.

MyBatis Interceptor的更多相关文章

  1. Mybatis Interceptor 拦截器原理 源码分析

    Mybatis采用责任链模式,通过动态代理组织多个拦截器(插件),通过这些拦截器可以改变Mybatis的默认行为(诸如SQL重写之类的),由于插件会深入到Mybatis的核心,因此在编写自己的插件前最 ...

  2. mybatis Interceptor拦截器代码详解

    mybatis官方定义:MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis ...

  3. mybatis interceptor 处理查询参数及查询结果

    拦截器:拦截update,query方法,处理查询参数及返回结果. /** * Created by windwant on 2017/1/12. */ @Intercepts({ @Signatur ...

  4. MyBatis源码分析(2)—— Plugin原理

    @(MyBatis)[Plugin] MyBatis源码分析--Plugin原理 Plugin原理 Plugin的实现采用了Java的动态代理,应用了责任链设计模式 InterceptorChain ...

  5. mybatis 打印sql 语句

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

  6. mybatis 控制台打印sql

    开发时调试使用 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBe ...

  7. 在mybatis执行SQL语句之前进行拦击处理

    转载自:http://blog.csdn.net/hfmbook/article/details/41985853 比较适用于在分页时候进行拦截.对分页的SQL语句通过封装处理,处理成不同的分页sql ...

  8. Mybatis拦截器介绍

    拦截器的一个作用就是我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,也可以在执行这些被拦截的方法时执行自己的逻辑而不再执行被拦截的方法.Mybatis拦截器设计的一个初 ...

  9. MyBatis查询两个字段,返回Map,一个字段作为key,一个字段作为value的实现

    1. 问题描述 在使用MyBatis,我们经常会遇到这种情况:SELECT两个字段,需要返回一个Map,其中第一个字段作为key,第二个字段作为value.MyBatis的MapKey虽然很实用,但并 ...

  10. MyBatis浅尝笔记

    MyBatis应属于一种轻量级的java持久层技术,它通过简单的SQL xml或注解,将数据库数据映射到接口与POJO.最近项目要用到mybatis,所以学习之后在这里做个总结,文中的示例以xml配置 ...

随机推荐

  1. [转帖]设置CMD默认代码页为65001或936

    https://www.cnblogs.com/songzhenhua/p/9312769.html 之前不知道怎么改的,CMD的代码页被默认设置成了65001   但我右击CMD标题,选择'默认值' ...

  2. [转帖]Postmark - 存储性能测试工具

    1. 引言 Postmark是由著名的NAS提供商NetApp开发,用来测试其产品的后端存储性能. Postmark主要用于测试文件系统在邮件系统或电子商务系统中性能,这类应用的特点是:需要频繁.大量 ...

  3. [转帖]Kafka 核心技术与实战学习笔记(七)kafka集群参数配置(上)

    一.Broker 端参数 Broke存储信息配置 log.dirs:非常重要,指定Broker需要使用的若干文件目录路径,没有默认值必须亲自指定. log.dir:他只能表示单个路径,补充上一个参数用 ...

  4. [转帖]vm内核参数之缓存回收drop_caches

    注:本文分析基于3.10.0-693.el7内核版本,即CentOS 7.4 1.关于drop_caches 通常在内存不足时,我们习惯通过echo 3 > /proc/sys/vm/drop_ ...

  5. 谈JVM xmx, xms等内存相关参数合理性设置

    作者:京东零售 刘乐 说到JVM垃圾回收算法的两个优化标的:吞吐量和停顿时长,并提到这两个优化目标是有冲突的.那么有没有可能提高吞吐量而不影响停顿时长,甚至缩短停顿时长呢?答案是有可能的,提高内存占用 ...

  6. bug的分类

    bug的分类 语法上的问题: 在循环的时候, 1.一定要注意这个循环的对象是否是空对象:空对象就不需要进行循环了, 判断一下,空对象就不需要进行循环了: 2.在XXX.a属性的时候,要注意这个对象是否 ...

  7. 【scikit-learn基础】--『回归模型评估』之可视化评估

    在scikit-learn中,回归模型的可视化评估是一个重要环节.它帮助我们理解模型的性能,分析模型的预测能力,以及检查模型是否存在潜在的问题.通过可视化评估,我们可以更直观地了解回归模型的效果,而不 ...

  8. 通过dotnet-dump分析生产环境docker容器部署的应用问题

    首先找到对应的docker id并exec进去,然后执行命令并更新apt包+下载procps和wget用于等下拉取dotnet-dump和查看线程 sed -i -e "s@deb.debi ...

  9. 【分享一个工具】根据 /metrics 路径下的文本信息,自动生成包含所有 metrics 的 grafana 报表

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 在做某个服务对应的 grafana 监控报表的时候发现,一 ...

  10. MySQL存储过程、索引、分表对比

    MySQL存储过程.索引和分表是用于提高查询效率的三种不同方法,它们各自对查询效率有不同的影响和应用场景.以下是它们的对比: MySQL存储过程: 影响查询效率: 存储过程通常不直接影响查询效率,因为 ...