Mybatis之插件開發之攔截器介紹

背景:mybatis插件(準確的說應該是around攔截器,因爲接口名是interceptor,而且invocation.proceed要自己調用,配置中叫插件)功能非常強大,可以讓我們無侵入式的對SQL的執行進行干涉,從SQL語句重寫、參數注入、結果集返回等每個主要環節,典型的包括權限控制檢查與注入、只讀庫映射、K/V翻譯、動態改寫SQL。

MyBatis默認支持對4大對象(Executor,StatementHandler,ParameterHandler,ResultSetHandler)上的方法執行攔截,具體支持的方法爲:

Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed),主要用於sql重寫。
ParameterHandler (getParameterObject, setParameters),用於參數處理。
ResultSetHandler (handleResultSets, handleOutputParameters),用於結果集二次處理。
StatementHandler (prepare, parameterize, batch, update, query),用於jdbc層的控制。
大多數情況下僅在Executor做插件比如SQL重寫、結果集脫敏,ResultSetHandler和StatementHandler僅在高級場景中使用,而且某些場景中非常有價值。

四大對象的在sql執行過程中的調用鏈如下:
在這裏插入圖片描述

1,攔截器接口介紹

Mybatis插件可以用來實現攔截器接口Interceptor,在實現類中攔截對象和方法進行處理。
先看攔截器接口,瞭解該接口中的每一個方法的作用和用法,代碼如下:

public interface Interceptor {

  Object intercept(Invocation invocation) throws Throwable;

  Object plugin(Object target);

  void setProperties(Properties properties);

}

1,setProperties:這個方法時用來傳遞插件的參數可以通過參數來改變插件的行爲。如何傳遞?如下:

	<plugins>
        <plugin interceptor="person.david.ssm.interceptor.CameHumpInterceptor">
        <property name="prop1" value="value1"/>
                <property name="prop1" value="value1"/>
				<property name="prop2" value="value2"/>
		</plugin>
    </plugins>

2,plugin:這個方法的參數就是攔截器要攔截的對象,該方法會在創建被攔截的接口實現類時被調用。通常實現方法如下:

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

3,interceptor:這個方法是Mybatis運行時要執行的攔截方法,該參數invocation可以獲得很多有用的信息,通常實現方法如下:

@Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object target = invocation.getTarget();
        onject result = invocation.proceed();
        return result;
    }

2,攔截器簽名介紹

除了需要實現攔截器接口外,還需要給實現類配置以下的攔截器註解。

@Intercepts和@Signature這兩個註解用來配置攔截器攔截的接口的方法,@Intercepts註解中的屬性是一個@Signature(簽名)數組,可以在同一個攔截器中同時攔截不同的接口和方法。

以攔截ResultSetHandler接口的handleResultSets方法爲例,配置簽名如下:

@Intercepts(
        @Signature(
                type = ResultSetHandler.class,
                method = "handleResultSets",
                args = {Statement.class})

)
@SuppressWarnings({"unchecked","rawtypes"})
public class ResultSetInterceptor implements Interceptor

@Signature註解包含以下三個屬性:


 - type:設置攔截的接口,可選值是前面提到的四個接口
 - method:設置攔截接口中的方法名,可選值是前面四個接口對應的方法,需要和接口匹配
 - args:設置攔截方法的參數類型數組,通過方法名和參數類型可以確定唯一一個方法

3,接口使用介紹

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章