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 介面,並指定想要攔截的方法簽名即可。
@Intercepts({
@Signature(
type = StatementHandler.class,
// StatementHandler.prepare方法
method = "prepare",
// StatementHandler.prepare方法的引數型別
args = {Connection.class,Integer.class}
)
})
public class ExamplePlugin implements Interceptor {
private Properties properties = new Properties();
@Override
public Object intercept(Invocation invocation) throws Throwable {
RoutingStatementHandler handler = (RoutingStatementHandler) invocation.getTarget();
BoundSql boundSql = handler.getBoundSql();
String sql = boundSql.getSql() + " limit 0,2";
// 利用反射,修改原來的sql
Field sqlField = boundSql.getClass().getDeclaredField("sql");
sqlField.setAccessible(true); // 解除私有限定
sqlField.set(boundSql, sql);
// implement pre processing if need
Object returnObject = invocation.proceed();
// implement post processing if need
return returnObject;
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
this.properties = properties;
}
}
<plugins>
<plugin interceptor="com.example.demo.ExamplePlugin">
<property name="someProperty" value="100"/>
</plugin>
</plugins>
本作品採用《CC 協議》,轉載必須註明作者和本文連結