乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Mybatis初始化過程簡單總結(jié)

       IT樂知 2020-12-07

      前面連續(xù)多篇文章都是在數(shù)據(jù)mybatis的初始化過程,目前基本完成,是時(shí)候做一個(gè)總結(jié)了。

      總覽

      首先回顧下最上層的測(cè)試代碼,實(shí)際上目前分析的還在測(cè)試代碼中與mybatis相關(guān)的第一步,具體如下圖:

      1目前位置

      目前還在構(gòu)建SqlSessionFactory這行代碼,這行代碼涉及了很多流程,前面也分析了很多,這里把分析的主要流程總結(jié)如下圖:

      2總覽圖

      上圖中只畫出了SqlSessionFactory初始化過程以及mapper的加載過程,由于其他比如Configuration的屬性、別名、插件、數(shù)據(jù)源配置、類型映射處理器的初始化過程比較簡單并沒有囊括進(jìn)去。

      上圖中紅色虛線框中的內(nèi)容是SqlSessionFactory初始化過程,以外的是mapper的加載流程。

      SqlSessionFactory加載過程

      SqlSessionFactory的初始化使用的是建造者模式,在SqlSessionFactoryBuilder中有多種方法創(chuàng)建SqlSessionFactory,但是最終都是創(chuàng)建一個(gè)XMLConfigBuilder對(duì)象調(diào)用它的parse方法得到Configuration對(duì)象,最終調(diào)用build(Configuration config)方法創(chuàng)建DefaultSqlSessionFactory對(duì)象,而DefaultSqlSessionFactory只有一個(gè)屬性config。

      所以SqlSessionFactory的初始化實(shí)際上是mybatis的全局配置類Configuration的初始化。而它的初始通過XMLConfigBuilder的parse方法實(shí)現(xiàn)。

      Configuration加載過程

      XMLConfigBuilder的parse方法調(diào)用的是“parseConfiguration(parser.evalNode("/configuration"));”這行代碼,parser是初始化XMLConfigBuilder時(shí)通過輸入流解析出來的XPathParser對(duì)象,XPathParser是mybatis框架用來解析xml文件的類。

      在拿到mybatis配置文件的configuration節(jié)點(diǎn)后,接下來就是對(duì)節(jié)點(diǎn)中的內(nèi)容進(jìn)行解析并填充到Configuration對(duì)象中。

      在parseConfiguration方法中可以了解到別名、插件、數(shù)據(jù)源配置、類型映射處理器的配置過程。

      從中可以知道自定義的插件都必須要實(shí)現(xiàn)Interceptor接口才行;

      我們最常見的第一個(gè)也是必須的數(shù)據(jù)源節(jié)點(diǎn)是environments,從源碼中了解到environments節(jié)點(diǎn)支持多個(gè)environment節(jié)點(diǎn),每個(gè)environment節(jié)點(diǎn)都有id,只有id和environments節(jié)點(diǎn)的default相等的節(jié)點(diǎn)才會(huì)被加載進(jìn)來

      在這其中還自定義一個(gè)類型映射處理器,實(shí)現(xiàn)了Java集合在保存到數(shù)據(jù)庫時(shí)自動(dòng)轉(zhuǎn)成字符串保存,并且在讀取出來時(shí)轉(zhuǎn)成Java集合。

      Mapper加載過程

      configuration加載最復(fù)雜的是mapper的加載過程了。在mybatis的配置xml文件中的mappers支持兩種子節(jié)點(diǎn):mapper、package。兩個(gè)節(jié)點(diǎn)出現(xiàn)有嚴(yán)格的先后順序,必須mapper節(jié)點(diǎn)在前面,package節(jié)點(diǎn)后面不能有任何mapper節(jié)點(diǎn)。

      mapper節(jié)點(diǎn)又有三個(gè)屬性resource、url、class,這三個(gè)屬性有且只能存在一個(gè),否則會(huì)拋出異常。其中resource、url是執(zhí)行mapper.xml文件進(jìn)行加載,class只是指定接口進(jìn)行加載。

      package節(jié)點(diǎn)是直接掃描指定包下面的所有接口,先根據(jù)接口加載對(duì)應(yīng)的xml,然后如果有注解在解析注解。所以我們現(xiàn)在只需要指定mapper接口所在包就能夠?qū)崿F(xiàn)注解和xml都支持。

      綜上我把加載mapper根據(jù)代碼流程分成了兩類:根據(jù)接口加載、根據(jù)xml文件加載

      根據(jù)接口加載流程圖在總覽圖的右側(cè),首先是直接調(diào)用configuration的addMappers或者addMapper方法,這個(gè)方法調(diào)用的是MapperRegistry類的addMappers或者addMapper方法,最終會(huì)初始化一個(gè)MapperAnnotationBuilder對(duì)象執(zhí)行他的parse方法。

      parse方法會(huì)先調(diào)用loadXmlResource方法加載接口可能對(duì)應(yīng)的mapper.xml文件,然后才是執(zhí)行注解的解析。最終在解析到具體每個(gè)方法時(shí)調(diào)用parseStatement方法解析方法上面所有的注解信息,并通過MapperBuilderAssistant類的addMappedStatement方法創(chuàng)建MappedStatement對(duì)象并保存到configuration的mappedStatements中。

      而根據(jù)xml加載mapper則是先根據(jù)resource、url創(chuàng)建XMLMapperBuilder對(duì)象并執(zhí)行它的parse方法,parse方法調(diào)用configurationElement方法處理xml文件中mapper節(jié)點(diǎn)的內(nèi)容,這個(gè)方法會(huì)解析出xml中的名稱空間、緩存、參數(shù)映射、結(jié)果映射等信息,在最后解析具體的select|insert|update|delete節(jié)點(diǎn)。

      解析語句節(jié)點(diǎn)時(shí)會(huì)創(chuàng)建XMLStatementBuilder對(duì)象,執(zhí)行對(duì)象parseStatementNode方法去解析語句節(jié)點(diǎn)中所有信息,最后通過MapperBuilderAssistant類的addMappedStatement方法創(chuàng)建MappedStatement對(duì)象并保存到configuration的mappedStatements中。

      可以看到無論是接口加載還是通過類加載最后都是生成一個(gè)MappedStatement對(duì)象并保存到configuration的mappedStatements中,mappedStatements是一個(gè)map,它是把MappedStatement對(duì)象id作為key,而id是如何生成的呢?

      通過接口方式加載的MappedStatement對(duì)象id是接口的類名+“.”+方法名,在通過xml方式加載的是通過mapper節(jié)點(diǎn)的namespace屬性的值(也就是名稱空間)+“.”+每個(gè)節(jié)點(diǎn)的id屬性值確定。

      MappedStatement還有另外一個(gè)關(guān)鍵屬性“SqlSource sqlSource;”。sqlSource是真正執(zhí)行sql的具體表現(xiàn),它提供了getBoundSql方法用來獲取正真執(zhí)行的sql,這個(gè)流程我們?cè)诤竺嬖敿?xì)分析。

      總結(jié)

      mybatis的初始化實(shí)際上是Configuration對(duì)象的初始化,是把mybatis的配置文件中信息加載到Configuration對(duì)象中的過程。

      而其中最復(fù)雜的是mapper加載,無論哪種方式加載mapper最終都是一條sql執(zhí)行語句對(duì)應(yīng)一個(gè)MappedStatement對(duì)象,生成的MappedStatement對(duì)象保存在Configuration對(duì)象的屬性“ Map<String, MappedStatement> mappedStatements”中, 在后面使用時(shí)通過Configuration對(duì)象獲取對(duì)應(yīng)sql執(zhí)行。

      Java程序員日常學(xué)習(xí)筆記,如理解有誤歡迎各位交流討論!

        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多