Mybatis經常使用用法之 Mybatis插件原理

這是我參與更文挑戰的第3天,活動詳情查看: 更文挑戰web

一:背景

通常狀況下,開源框架都會提供插件或其餘形式的拓展點,供開發者自行拓展。這樣的好處是顯而易見的,一是增長了框架的靈活性。二是開發者能夠結合實際需求,對框架進行拓展,使其可以更好的工做。以MyBatis爲例,咱們可基於MyBatis插件機制實現分頁、分表,監控等功能。因爲插件和業務無關,業務也沒法感知插件的存在。所以能夠無感植入插件,在無形中加強功能sql

二:Mybatis插件介紹

Mybatis做爲一個應用普遍的優秀的ORM開源框架,這個框架具備強大的靈活性,在四大組件 (Executor、StatementHandler、ParameterHandler、ResultSetHandler)處提供了簡單易用的插件擴展機制。Mybatis對持久層的操做就是藉助於四大核心對象。MyBatis支持用插件對四大核心對象進行攔截,對mybatis來講插件就是攔截器,用來加強核心對象的功能,加強功能本質上是藉助於底層的 動態代理實現的,換句話說,MyBatis中的四大對象都是代理對象markdown

MyBatis所容許攔截的方法以下:mybatis

  • 執行器Executor (update、query、commit、rollback等方法);
  • SQL語法構建器StatementHandler (prepare、parameterize、batch、updates query等方法);
  • 參數處理器ParameterHandler (getParameterObject、setParameters方法);
  • 結果集處理器ResultSetHandler (handleResultSets、handleOutputParameters等方法);

三:Mybatis插件原理

在四大對象建立的時候app

  • 一、每一個建立出來的對象不是直接返回的,而interceptorChain.pluginAll(parameterHandler);
  • 二、獲取到全部的Interceptor (攔截器)(插件須要實現的接口);調用 interceptor.plugin(target);返回 target 包裝後的對象
  • 三、插件機制,咱們可使用插件爲目標對象建立一個代理對象;AOP (面向切面)咱們的插件能夠爲四大對象建立出代理對象,代理對象就能夠攔截到四大對象的每個執行;

攔截框架

插件具體是如何攔截並附加額外的功能的呢?以ParameterHandler來講post

public ParameterHandler newParameterHandler(MappedStatement mappedStatement,Object object, BoundSql sql, InterceptorChain interceptorChain){
    ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement,object,sql);
    parameterHandler = (ParameterHandler)
    interceptorChain.pluginAll(parameterHandler);
    return parameterHandler;
}
public Object pluginAll(Object target) {
    for (Interceptor interceptor : interceptors) 
    {
        target = interceptor.plugin(target);
    }
    return target;
}
複製代碼

interceptorChain保存了全部的攔截器(interceptors),是mybatis初始化的時候建立的。調用攔截器鏈中的攔截器依次的對目標進行攔截或加強。interceptor.plugin(target)中的target就能夠理解爲mybatis 中的四大對象。返回的target是被重重代理後的對象ui

若是咱們想要攔截Executor的query方法,那麼能夠這樣定義插件:url

@Intercepts({
    @Signature(
        type = Executor.class,
        method = "query",
        args={MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class}
        )
})
public class ExeunplePlugin implements Interceptor {
//省略邏輯 
}
複製代碼

除此以外,咱們還需將插件配置到sqlMapConfig.xml中。spa

<plugins>
    <plugin interceptor="com.lagou.plugin.ExamplePlugin"></plugin>
</plugins>
複製代碼

這樣MyBatis在啓動時能夠加載插件,並保存插件實例到相關對象(InterceptorChain,攔截器鏈) 中。待準備工做作完後,MyBatis處於就緒狀態。咱們在執行SQL時,須要先經過DefaultSqlSessionFactory 創 建 SqlSession。Executor 實例會在建立 SqlSession 的過程當中被建立, Executor實例建立完畢後, MyBatis會經過JDK動態代理爲實例生成代理類。這樣,插件邏輯便可在 Executor相關方法被調用前執行。

以上就是MyBatis插件機制的基本原理.

但願對各位小夥伴有所幫助

相關文章
相關標籤/搜索