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. 配置Maven项目的pom.xml时遇到input contained no data问题

    1.问题 2.解决 我发现每次当我修改一些部分之后,就会遇到这个问题 我遵循了他的建议重新排列标记属性,然后重新加载就解决了报错 个人怀疑是修改后并没有识别之类的? 最终原因:是我在Maven项目中的 ...

  2. SpringBoot02:运行原理初探

    @EnableAutoConfiguration @EnableAutoConfiguration:开启自动配置功能 以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置 @Ena ...

  3. 百度网盘(百度云)SVIP超级会员共享账号每日更新(2023.12.21)

    一.百度网盘SVIP超级会员共享账号 可能很多人不懂这个共享账号是什么意思,小编在这里给大家做一下解答. 我们多知道百度网盘很大的用处就是类似U盘,不同的人把文件上传到百度网盘,别人可以直接下载,避免 ...

  4. Oracle数据类型的简单学习之一

    Oracle数据类型的简单学习之一 背景 因为信创安可替代的发展 有很多项目提到了数据库切换到国产数据库的要求. 一般情况是要求从Oracle/SQLServer 迁移到国产的: 达梦/瀚高/人大金仓 ...

  5. [转帖]How to Resolve ORA-3136 Inbound Connection Timed Out

    https://logic.edchen.org/how-to-resolve-ora-3136-inbound-connection-timed-out/#:~:text=ORA-03136%3A% ...

  6. [转帖]sqlplus与shell互相传值的几种情况

    https://www.cnblogs.com/youngerger/p/9068888.html sqlplus与shell互相传值的几种情况 情况一:在shell中最简单的调用sqlplus $c ...

  7. [转帖]【Python】计算程序运行时间的方法总结

    一.第一种方法 利用time包: import time def test(): start_time = time.time() # 记录程序开始运行时间 s = 0 for i in range( ...

  8. [转帖]聊聊我对 GraphQL 的一些认知

    https://www.modb.pro/db/139451 作者简介:haohongfan 是 Apache Dubbogo Committer,目前就职于京东,擅长高并发架构设计.公众号 HHFC ...

  9. [转帖]linux下/proc/sysrq-trigger详解

    /proc/sysrq-trigger详解 这是一组"魔术组合键",只要内核没有被完全锁住,不管内核在做什么事情,使用这些组合键能即时打印出内核的信息. 使用SysRq组合键是了解 ...

  10. Intel 第四代志强可扩展SKU