mybatis拦截器的使用(输出日志或sql语句)

原创 2016年08月28日 14:52:48

拦截器的一个作用就是我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,也可以在执行这些被拦截的方法时执行自己的逻辑而不再执行被拦截的方法。Mybatis拦截器设计的一个初衷就是为了供用户在某些时候可以实现自己的逻辑而不必去动Mybatis固有的逻辑。mybatis拦截器一般用于分页插件、输出日志、sql等。使用的方法如下:

首先要实现mybatis的Interceptor接口,

实现它的三个方法:

Object intercept(Invocation invocation) throws Throwable;

Object plugin(Object target);

void setProperties(Properties properties);
plugin方法是拦截器用于封装目标对象的,通过该方法我们可以返回目标对象本身,也可以返回一个它的代理。当返回的是代理的时候我们可以对其中的方法进行拦截来调用intercept方法,当然也可以调用其他方法,这点将在后文讲解。

setProperties方法是用于在Mybatis配置文件中指定一些属性的。

plugin方法中我们可以决定是否要进行拦截进而决定要返回一个什么样的目标对象。而intercept方法就是要进行拦截的时候要执行的方法。

下面例子本来相用于记录日志到数据库,但是由于mybatis底层无法注入spring的对象,所以,只能用于输出日志。

@Intercepts({@Signature(method = "update", type = Executor.class, args = {MappedStatement.class, Object.class})})
public class LogInterceptor implements Interceptor {
    /**
     * 注解拦截接口的方法
     * Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
     * ParameterHandler (getParameterObject, setParameters)
     * ResultSetHandler (handleResultSets, handleOutputParameters)
     * StatementHandler (prepare, parameterize, batch, update, query)
     */

    private static final Logger LOGGER = LoggerFactory.getLogger(LogInterceptor.class);

    private Properties properties;

    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        // 获取执行的方法
        if (args.length > 1) {
            // 传入的对象
            Object obj = args[1];
            if (obj instanceof Log) {
                // 若是日志对象 则直接跳过
                return invocation.proceed();
            }
            saveLog(args[0], obj);
        }
        return invocation.proceed();
    }

    private void saveLog(Object arg, Object obj) {
        Log log = new Log();
        log.setCreateTime(DateUtils.now());
        log.setModifyTime(DateUtils.now());
        MappedStatement mappedStatement = (MappedStatement) arg;
        // 执行的方法名
        String name = mappedStatement.getSqlCommandType().name();
        String change = JsonMapper.toJson(obj);
        if (name.startsWith("INSERT")) {
            log.setType("新增" + obj.getClass().getSimpleName());
            log.setNewContent(change);
        } else if (name.startsWith("UPDATE")) {
            log.setType("修改" + obj.getClass().getSimpleName());
            log.setNewContent(change);
        } else if (name.startsWith("DELETE")) {
            log.setType("删除" + obj.getClass().getSimpleName());
            log.setOldContent(change);
        }

        LOGGER.info("----------------------------------------------");
        LOGGER.info(JsonMapper.toJson(log));
        LOGGER.info("----------------------------------------------");
    }

    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

}
类上面必须添加@Intercepts注解,@Signature,代表拦截点,

@Intercepts({@Signature(method = "update", type = Executor.class, args = {MappedStatement.class, Object.class})})
method表示需要拦截的方法,mybatis有

update, query, flushStatements, commit, rollback, getTransaction, close, isClosed
方法,其中,update包括新增、修改、删除等方法,query用于查询,其它的基本用不到。

type表示拦截的接口类型,有Executor、StatementHandler、ParameterHandler和ResultSetHandler。

args表示拦截的参数类型,有MappedStatement、Object、RowBounds和ResultHandler等等.


        编写完拦截器,需要在配置文件中注册拦截器,在sqlMapConfig配置文件中加上

<?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="cacheEnabled" value="true"/>
      <setting name="lazyLoadingEnabled" value="true"/>
      <setting name="multipleResultSetsEnabled" value="true"/>
      <setting name="useColumnLabel" value="true"/>
      <setting name="useGeneratedKeys" value="false"/>
    </settings>
    
    <plugins>
        <plugin interceptor="com.tc.itfarm.commons.interceptor.LogInterceptor"></plugin>
    </plugins>
</configuration>
启动项目测试即可,输出的日志如下:

2016-08-28 14:48:02  [ http-apr-8888-exec-8:70630 ] - [ INFO ]  ----------------------------------------------
2016-08-28 14:48:02  [ http-apr-8888-exec-8:70634 ] - [ INFO ]  {"recordId":null,"type":"修改User","oldContent":null,"newContent":"{\"recordId\":1,\"username\":\"wdd\",\"telephone\":\"18888888888\",\"sex\":2,\"password\":null,\"age\":22,\"status\":1,\"address\":\"安徽灵璧1\",\"photo\":null,\"email\":\"asdds\",\"qq\":\"812908087\",\"nickname\":\"爱吃猫的鱼1\",\"registerTime\":null,\"modifyTime\":1472366881824}","userId":null,"username":null,"createTime":1472366881824,"modifyTime":1472366881824}
2016-08-28 14:48:02  [ http-apr-8888-exec-8:70634 ] - [ INFO ]  ----------------------------------------------

若要插入到数据库,必须new一个dao对象操作


版权声明:本文为博主原创文章,未经博主允许不得转载。

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

比较适用于在分页时候进行拦截。对分页的SQL语句通过封装处理,处理成不同的分页sql。 实用性比较强。 import java.sql.Connection; import java.sql.Pre...
  • hfmbook
  • hfmbook
  • 2014年12月17日 19:41
  • 45152

MyBatis拦截器动态修改SQL语句及参数值(场景:查询中字段值中特殊字符自动转义)

拦截器基础: 配置
  • fencer911
  • fencer911
  • 2014年09月22日 17:04
  • 20308

mybatis 拦截器拦截所有sql

package org.geekworld.core.mybatis; import com.alibaba.fastjson.JSON; import org.apache.ibatis.cach...
  • wuxifu001
  • wuxifu001
  • 2016年12月26日 16:34
  • 5477

【myBatis】Mybatis中的拦截器

Mybatis 拦截器介绍 1.1 目录 1.2 前言 1.3 Interceptor接口 1.4 注册拦截器 1.5 Mybatis可拦截的方法 ...
  • moshenglv
  • moshenglv
  • 2016年09月29日 10:55
  • 17057

mybatise自定义插件或者叫mybatise拦截器,动态修改sql语句

package com.teamsun.net.common.utils; import java.lang.reflect.Constructor; import java.util.Prope...
  • zhongbaolin
  • zhongbaolin
  • 2015年05月28日 10:58
  • 1961

Mybatis SQL拦截器实现

主要功能:通过log4j配置mybatis的打印,只能输出到控制台,而并非真正能够实现sql的获取,本文主要通过拦截器实现sql的拦截,进而对sql进行相应的操作。 起因:因项目需要,服务器要配成双机...
  • u013256816
  • u013256816
  • 2015年08月27日 16:41
  • 5567

MyBatis源码剖析 - MyBatis 插件之拦截器(Interceptor)实现原理

在上一篇文章:MyBatis 教程 - MyBatis插件(Plugins)开发 中已经介绍了如何去开发一个MyBatis 插件,本文将结合MyBatis 源码来揭秘MyBatis Plugins内部...
  • FX_SKY
  • FX_SKY
  • 2017年02月18日 12:18
  • 4881

Mybatis那些事-拦截器(Plugin+Interceptor)

Mybatis的拦截器实现机制,使用的是JDK的InvocationHandler. 当我们调用ParameterHandler,ResultSetHandler,StatementHandler,E...
  • yhjyumi
  • yhjyumi
  • 2015年10月17日 00:44
  • 16444

mybatis拦截器介绍和分页插件

本文转载自:http://haohaoxuexi.iteye.com/blog/1851081#_Toc3543305681.1前言拦截器的一个作用就是我们可以拦截某些方法的调用,我们可以选择在这些被...
  • qq_27739989
  • qq_27739989
  • 2016年05月26日 15:35
  • 1299

Mybatis中的拦截器

先看一下mybatis拦截器的用法和用途,先用为ibatis3提供基于方言(Dialect)的分页查询的例子来看一下吧!源码:@Intercepts({@Signature(        type=...
  • lhch1984
  • lhch1984
  • 2011年07月26日 22:02
  • 6753
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:mybatis拦截器的使用(输出日志或sql语句)
举报原因:
原因补充:

(最多只允许输入30个字)