天天看點

Mybatis --- 插件開發Mybatis — 插件開發

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注解完成插件簽名
      Mybatis --- 插件開發Mybatis — 插件開發
    • 2)在全局配置檔案中注冊插件
      Mybatis --- 插件開發Mybatis — 插件開發
  • 插件完整内容:

/**
 * 完成插件簽名:
 *		告訴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屬性的值

繼續閱讀