mybatis插件(拦截器)

1、作用

可以在sql执行前后 结果映射 参数解析阶段做拦截处理(AOP)

如:日志打印 性能监控等

 

2、拦截的4个对象

Execute StatementHandle ParameterHandle ResultHandle

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed),主要用于sql重写。
  • ParameterHandler (getParameterObject, setParameters),用于参数处理。
  • ResultSetHandler (handleResultSets, handleOutputParameters),用于结果集二次处理。
  • StatementHandler (prepare, parameterize, batch, update, query),用于jdbc层的控制。

 

 

3、使用

定义哪个对象 哪个方法进行拦截

如:plugin方法返回代理对象

 

 

4、原理

具体的方法定义可以参见每个类方法的签名,这里就不详细展开了。这四个类被创建后不是直接返回,而是创执行了interceptorChain.pluginAll(parameterHandler)才返回。如下所示:

pluginAll最终调用每个拦截器的plugin方法,返回代理对象,如果有多个拦截器,就会一层层代理。

复制代码
//Configuration 中
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
    ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
    parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
    return parameterHandler;
}
​
public ResultSetHandler newResultSetHandler(Executor executor, MappedStatement mappedStatement, RowBounds rowBounds, ParameterHandler parameterHandler,
                                            ResultHandler resultHandler, BoundSql boundSql) {
    ResultSetHandler resultSetHandler = new DefaultResultSetHandler(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds);
    resultSetHandler = (ResultSetHandler) interceptorChain.pluginAll(resultSetHandler);
    return resultSetHandler;
}
​
public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
    StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
    statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
    return statementHandler;
}
​
public Executor newExecutor(Transaction transaction) {
    return newExecutor(transaction, defaultExecutorType);
}
​
// Execute默认使用SimpleExecutor public Executor newExecutor(Transaction transaction, ExecutorType executorType) {    executorType = executorType == null ? defaultExecutorType : executorType;    executorType = executorType == null ? ExecutorType.SIMPLE : executorType;    Executor executor;    if (ExecutorType.BATCH == executorType) {        executor = new BatchExecutor(this, transaction);   } else if (ExecutorType.REUSE == executorType) {        executor = new ReuseExecutor(this, transaction);   } else {        executor = new SimpleExecutor(this, transaction);   }    if (cacheEnabled) {        executor = new CachingExecutor(executor);   }    executor = (Executor) interceptorChain.pluginAll(executor);    return executor; }
 

5、总结

使用的设计模式:代理模式、责任链模式

参考:

https://www.cnblogs.com/chenpi/p/10498921.htm

https://www.cnblogs.com/zhjh256/p/11516878.html

https://my.oschina.net/u/4365042/blog/3344199l

posted @ 2020-08-08 20:37  蓝天随笔  阅读(1010)  评论(0编辑  收藏  举报