溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Mybatis執(zhí)行流程的源碼分析

發(fā)布時間:2021-10-21 09:59:14 來源:億速云 閱讀:131 作者:柒染 欄目:大數(shù)據(jù)

今天就跟大家聊聊有關(guān)Mybatis執(zhí)行流程的源碼分析,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

一:Mybatis源碼分析流程

public static void main(String[] args) {

    try {
        // 基本mybatis環(huán)境
        // 1.定義mybatis_config文件地址
        String resources = "mybatis_config.xml";
        // 2.獲取InputStreamReaderIo流
        Reader reader = Resources.getResourceAsReader(resources);
        // 3.獲取SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        // 4.獲取Session
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 5.操作Mapper接口
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        UserEntity user = mapper.getUser(2);
        System.out.println(user.getName());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

總結(jié):

1、讀取Mybatis配置文件信息

2、獲取SqlSessionFactory

a.使用XMLMappperBuilder解析Mybatis配置文件,封裝成Environment對象,再把Environment對象設(shè)置給Configuration對象;

b.調(diào)用ConfigurationElement函數(shù),最終執(zhí)行addMappedStatement方法,將mapper配置文件中的每一條SQL語句封裝成mappedStatement對象,作為value保存在HashMap集合中;

c.進(jìn)入addLoaderResource方法,使用HashSet集合存放mybatis的mapper.xml 映射文件路徑地址;

d.進(jìn)入bindMapperForNamespace()方法,通過namespace使用Java反射機(jī)制找到mapper接口,再調(diào)用addMapper()方法,判斷是否是接口類型,是否注冊過(注冊過則拋出異常)其中mapperRegistry通過HashMap保存mapper接口,【key:接口;value:MapperProxyFactory】

3、獲取session

a.進(jìn)入openSession()方法,執(zhí)行newExecutor()方法創(chuàng)建執(zhí)行器;

b.先創(chuàng)建 SimpleExecutor簡單執(zhí)行器,再判斷是否開啟了二級緩存,默認(rèn)是開啟的,就會去創(chuàng)建CacheExecutor緩存執(zhí)行器,

c.執(zhí)行interceptorChain.pluginAll()方法,責(zé)任鏈設(shè)計模式,底層使用動態(tài)代理技術(shù),使開發(fā)者可以自定義插件開發(fā),只需要實現(xiàn)Interceptor接口,并指定想要攔截的方法簽名即可,最后返回執(zhí)行器;

4、操作mapper接口

a.調(diào)用getMapper()方法,最終執(zhí)行mapperProxyFactory.newInstance(sqlSession)方法創(chuàng)建代理類MapperProxy;

b.當(dāng)我們調(diào)用mapper,getUser()方法的時候,就會去執(zhí)行MapperProxy代理類的invoke()方法;

c.判斷mapper接口是否有實現(xiàn)類,顯然我們沒有實現(xiàn)類,則調(diào)用cacheMapperMethod()方法去緩存中獲取要代理的方法method;

d.進(jìn)入cacheMapperMethod()方法先去查找緩存中有沒有,沒有的話將mapper配置文件中配置的SQL語句和對應(yīng)的mapper接口方法進(jìn)行關(guān)聯(lián)并放入map緩存中,后期直接走緩存了,最后執(zhí)行execute()方法;

e.執(zhí)行execute()方法,最終調(diào)用selectOne()方法;

f.進(jìn)入selectOne()方法,底層還是查詢所有的,但是取第一個,查詢多個的話會拋出異常;

g.進(jìn)入selectList()方法,調(diào)用getMapperStatement()方法獲取對應(yīng)的SQL語句;

h.執(zhí)行query()方法進(jìn)行查詢,判斷如果開啟了二級緩存并且配置了二級緩存存儲介質(zhì)(Redis,EhCache..)則先走二級緩存中查詢數(shù)據(jù),第一次查詢是沒有緩存數(shù)據(jù)的,則刷新緩存配置,清除緩存。

i.二級緩存(sessionFactory)中沒有查詢到數(shù)據(jù),就回去執(zhí)行BaseExecutor去查詢 HashMap一級緩存中(sqlSession)是否有緩存數(shù)據(jù),一級緩存(PerpetualCache)存放在內(nèi)存中的,同理也是沒有的,最后查詢數(shù)據(jù)庫DB。

j.將從數(shù)據(jù)庫查詢出來的數(shù)據(jù)緩存到一級緩存中,再把一級緩存中的數(shù)據(jù)同步到二級緩存,添加到二級緩存之前先添加到getTransactionalCache的entritiesToAddOnCommit的map集合中臨時緩存起來;

k.調(diào)用executor.close()方法循環(huán)迭代TransactionCache,最后將臨時map緩存數(shù)據(jù)提交到二級緩存中,如果事務(wù)回滾,則會將緩存數(shù)據(jù)清除掉。

看完上述內(nèi)容,你們對Mybatis執(zhí)行流程的源碼分析有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI