Mybatis之外掛攔截
阿新 • • 發佈:2018-12-06
參考:http://www.mybatis.org/mybatis-3/zh/configuration.html#plugins
MyBatis 允許你在已對映語句執行過程中的某一點進行攔截呼叫。預設情況下,MyBatis 允許使用外掛來攔截的方法呼叫包括:
- Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
- ParameterHandler (getParameterObject, setParameters)
- ResultSetHandler (handleResultSets, handleOutputParameters)
- StatementHandler (prepare, parameterize, batch, update, query)
這些類中方法的細節可以通過檢視每個方法的簽名來發現,或者直接檢視 MyBatis 發行包中的原始碼。 如果你想做的不僅僅是監控方法的呼叫,那麼你最好相當瞭解要重寫的方法的行為。 因為如果在試圖修改或重寫已有方法的行為的時候,你很可能在破壞 MyBatis 的核心模組。 這些都是更低層的類和方法,所以使用外掛的時候要特別當心。
通過 MyBatis 提供的強大機制,使用外掛是非常簡單的,只需實現 Interceptor 介面,並指定想要攔截的方法簽名即可。
例如攔截SQL執行時間的外掛:
package com.javartisan.mybatis.plugin; import com.jd.ad.datamill.utils.SqlHelper; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.plugin.*; import org.apache.ibatis.session.ResultHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.sql.Statement; import java.util.Properties; @Intercepts(@Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class})) public class SqlInterceptor implements Interceptor { private static final Logger LOGGER = LoggerFactory.getLogger(SqlInterceptor.class); private Properties properties; @Override public Object intercept(Invocation invocation) throws Throwable { Object target = invocation.getTarget(); long startTime = System.currentTimeMillis(); StatementHandler statementHandler = (StatementHandler) target; try { return invocation.proceed(); } finally { long endTime = System.currentTimeMillis(); long sqlCost = endTime - startTime; BoundSql boundSql = statementHandler.getBoundSql(); String sql = SqlHelper.formatSql(boundSql); LOGGER.info("QuerySQL:[" + sql + "],執行耗時:[" + sqlCost + "ms]"); } } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { this.properties = properties; } }
重點部分:
@Intercepts(@Signature(type = StatementHandler.class, method = "query",args = {Statement.class, ResultHandler.class}))
其中Signature為設定攔截條件,type表示要攔截的型別,method表示要攔截的方法,是type中的一個方法;args為該方法的引數;
注意:type型別必須是Mybatis支援的型別,否則無法攔截!!!!