Mybatis原理

1Mybatis插件介紹

Mybati s作為?個(gè)應(yīng)??泛的優(yōu)秀的ORM開源框架,這個(gè)框架具有強(qiáng)?的靈活性,在四?組件(Executor、StatementHandler、ParameterHandler、ResultSetHandler)處提供了簡單易?的插 件擴(kuò)展機(jī)制。Mybatis對持久層的操作就是借助于四?核?對象。MyBatis?持?插件對四?核?對象進(jìn) ?攔截,對mybatis來說插件就是攔截器,?來增強(qiáng)核?對象的功能,增強(qiáng)功能本質(zhì)上是借助于底層的 動(dòng)態(tài)代理實(shí)現(xiàn)的,換句話說,MyBatis中的四?對象都是代理對象


image.png

2 Mybatis插件原理

MyBatis所允許攔截的?法如下:
執(zhí)?器Executor (update、query、commit、rollback等?法);
SQL語法構(gòu)建器StatementHandler (prepare、parameterize、batch、updates query等? 法);
參數(shù)處理器ParameterHandler (getParameterObject、setParameters?法);
結(jié)果集處理器ResultSetHandler (handleResultSets、handleOutputParameters等?法);

Mybatis插件原理
在四?對象創(chuàng)建的時(shí)候
1、每個(gè)創(chuàng)建出來的對象不是直接返回的,?是interceptorChain.pluginAll(parameterHandler);
2、獲取到所有的Interceptor (攔截器)(插件需要實(shí)現(xiàn)的接?);調(diào)? interceptor.plugin(target);返 回 target 包裝后的對象
3、插件機(jī)制,我們可以使?插件為?標(biāo)對象創(chuàng)建?個(gè)代理對象;AOP (?向切?)我們的插件可 以
為四?對象創(chuàng)建出代理對象,代理對象就可以攔截到四?對象的每?個(gè)執(zhí)?;
攔截
插件具體是如何攔截并附加額外的功能的呢?以ParameterHandler來說


    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初始化的時(shí)候創(chuàng)建的。調(diào)?攔截器鏈中的攔截器依次的對?標(biāo)進(jìn)?攔截或增強(qiáng)。interceptor.plugin(target)中的target就可以理解為mybatis中的四?對象。返回的target是被重重代理后的對象.
如果我們想要攔截Executor的query?法,那么可以這樣定義插件:

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

這樣MyBatis在啟動(dòng)時(shí)可以加載插件,并保存插件實(shí)例到相關(guān)對象(InterceptorChain,攔截器鏈) 中。待準(zhǔn)備?作做完后,MyBatis處于就緒狀態(tài)。我們在執(zhí)?SQL時(shí),需要先通過DefaultSqlSessionFactory創(chuàng)建 SqlSession。Executor 實(shí)例會(huì)在創(chuàng)建 SqlSession 的過程中被創(chuàng)建, Executor實(shí)例創(chuàng)建完畢后,MyBatis會(huì)通過JDK動(dòng)態(tài)代理為實(shí)例?成代理類。這樣,插件邏輯即可在 Executor相關(guān)?法被調(diào)?前執(zhí)?。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容