java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > mybatis拦截器的使用方式

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

作者:春风十里不及你

这篇文章主要介绍了mybatis拦截器的使用方式(输出日志或sql语句),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

拦截器的一个作用

是我们可以拦截某些方法的调用,我们可以选择在这些被拦截的方法执行前后加上某些逻辑,也可以在执行这些被拦截的方法时执行自己的逻辑而不再执行被拦截的方法。

Mybatis拦截器设计的一个初衷就是为了供用户在某些时候可以实现自己的逻辑而不必去动Mybatis固有的逻辑。mybatis拦截器一般用于分页插件、输出日志、sql等。

使用的方法

首先要实现mybatis的Interceptor接口,

实现它的三个方法:

Object intercept(Invocation invocation) throws Throwable;
Object plugin(Object target);
void setProperties(Properties properties);

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用于查询,其它的基本用不到。

编写完拦截器

需要在配置文件中注册拦截器,在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对象操作

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文