Mybatis — 插件開發
* 上一篇說到Mybatis中的逆向工程 “MBG”Mybatis — 逆向工程
* 這一篇主要來講解Mybatis中的插件開發
了解:
- MyBatis在四大對象的建立過程中,都會有插件進行介入。插件可以利用動态代理機制一層層的包裝目标對象,而實作在目标對象執行目标方法之前進行攔截的效果。
- MyBatis 允許在已映射語句執行過程中的某一點進行攔截調用。
預設情況下,MyBatis 允許使用插件來攔截的方法調用包括:
• Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
• ParameterHandler (getParameterObject, setParameters)
• ResultSetHandler (handleResultSets, handleOutputParameters)
• StatementHandler (prepare, parameterize, batch, update, query)
插件開發
-
插件開發步驟:
- 1)編寫插件實作Interceptor接口,并使用@Intercepts注解完成插件簽名
- 2)在全局配置檔案中注冊插件
-
插件完整内容:
/**
* 完成插件簽名:
* 告訴MyBatis目前插件用來攔截哪個對象的哪個方法
*/
@Intercepts(
{
@Signature(type=StatementHandler.class,method="parameterize",args=java.sql.Statement.class)
})
public class MyFirstPlugin implements Interceptor{
/**
* intercept:攔截:
* 攔截目标對象的目标方法的執行;
*/
@Override
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("MyFirstPlugin...intercept:"+invocation.getMethod());
//動态的改變一下sql運作的參數:本來是查詢 1 号員工,現在變成從資料庫查詢 2 号員工
Object target = invocation.getTarget();
System.out.println("目前攔截到的對象:"+target);
//拿到:StatementHandler==>ParameterHandler===>parameterObject
//拿到target的中繼資料
MetaObject metaObject = SystemMetaObject.forObject(target);
Object value = metaObject.getValue("parameterHandler.parameterObject");
System.out.println("sql語句用的參數是:"+value);
//修改完sql語句要用的參數
metaObject.setValue("parameterHandler.parameterObject", 2);
//執行目标方法
Object proceed = invocation.proceed();
//傳回執行後的傳回值
return proceed;
}
/**
* plugin:
* 包裝目标對象的:包裝:為目标對象建立一個代理對象
*/
@Override
public Object plugin(Object target) {
//我們可以借助Plugin的wrap方法來使用目前Interceptor包裝我們目标對象
System.out.println("MyFirstPlugin...plugin:mybatis将要包裝的對象"+target);
Object wrap = Plugin.wrap(target, this);
//傳回為目前target建立的動态代理
return wrap;
}
/**
* setProperties:
* 将插件注冊時 的property屬性設定進來
*/
@Override
public void setProperties(Properties properties) {
System.out.println("插件配置的資訊:"+properties);
}
}
-
Interceptor接口:
- Intercept:攔截目标方法執行
- plugin:生成動态代理對象,可以使用MyBatis提 供的Plugin類的wrap方法
- setProperties:注入插件配置時設定的屬性
插件原理
-
1)按照插件注解聲明,按照插件配置順序調用插件plugin方法,生成被攔截對象的動态代理
-
2)多個插件依次生成目标對象的代理對象,層層包裹,先聲明的先包裹;形成代理鍊
-
3)目标方法執行時依次從外到内執行插件的intercept方法。
-
4)多個插件情況下,我們往往需要在某個插件中分離出目标對象。可以借助MyBatis提供的SystemMetaObject類來進行擷取最後一層的h以及target屬性的值