詳解Mybatis核心類SqlSessionFactory的構建
請大家搬好小板凳,指北君將會用最通俗易懂,圖文并茂的方式,給大家深入剖析 Mybatis 的實現原理。
本篇文章我們首先解析 SqlSessionFactory 的創(chuàng)建過程。
1、實例代碼
在實例代碼中,我們在測試類中寫了一個 init() 方法,里面包括了 SqlSessionFactory 的構建,分為兩步。
第一步:讀取配置文件 mybatis-config.xml 輸入流
第二步:根據輸入流構建 SqlSessionFactory;
public?void?init()?{ ????//定義mybatis全局配置文件 ????String?resource?=?"mybatis-config.xml"; ????//加載?mybatis?全局配置文件 ????InputStream?inputStream?=?null; ????try?{ ????????inputStream?=?Resources.getResourceAsStream(resource); ????}?catch?(IOException?e)?{ ????????e.printStackTrace(); ????} ????//構建sqlSession的工廠 ????sessionFactory?=?new?SqlSessionFactoryBuilder().build(inputStream); }
沒什么難的,去掉 try-catch,也就兩行代碼。
InputStream?inputStream?=?Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory?sessionFactory?=?new?SqlSessionFactoryBuilder().build(inputStream);
是的,那只是你以為的兩行代碼,其實......
話不多說,指北君就來給大家揭秘這冰山下面的東西。
2、代碼剖析
根據上面的時序圖,我們分析根據源碼分析每個步驟。
①、獲取配置文件輸入流
InputStream?inputStream?=?Resources.getResourceAsStream("mybatis.config.xml");
這里沒什么好說的,就是獲取配置文件的輸入流。
②、build(in)
這里的 in 就是上一步獲取的輸入流 inputStream。
??public?SqlSessionFactory?build(InputStream?inputStream)?{ ????return?build(inputStream,?null,?null); ??}
在進入到 build 方法:
??public?SqlSessionFactory?build(InputStream?inputStream,?String?environment,?Properties?properties)?{ ????try?{ ??????XMLConfigBuilder?parser?=?new?XMLConfigBuilder(inputStream,?environment,?properties); ??????return?build(parser.parse()); ????}?catch?(Exception?e)?{ ??????throw?ExceptionFactory.wrapException("Error?building?SqlSession.",?e); ????}?finally?{ ??????ErrorContext.instance().reset(); ??????try?{ ????????inputStream.close(); ??????}?catch?(IOException?e)?{ ????????//?Intentionally?ignore.?Prefer?previous?error. ??????} ????} ??}
③、XMLConfigBuilder(in)
這一段代碼是為了解析我們的配置文件,配置文件是 XML形式 ,我在之前的博客介紹過解析 XML 的幾種方式。
一種是基于樹的結構來解析的稱為DOM;另一種是基于事件流的形式稱為SAX和(StAX)
兩者各有優(yōu)缺點,我這里不做詳細說明,想了解的可以看我之前的文章。
而 Mybatis 使用的是 DOM 形式,并結合 XPath 來解析配置文件。
④、parse()
????public?Configuration?parse()?{ ????????if?(this.parsed)?{ ????????????throw?new?BuilderException("Each?XMLConfigBuilder?can?only?be?used?once."); ????????}?else?{ ????????????this.parsed?=?true; ????????????this.parseConfiguration(this.parser.evalNode("/configuration")); ????????????return?this.configuration; ????????} ????}
從 /configuration 標簽處開始解析。然后我們進入到 this.parseConfiguration() 方法中:
????private?void?parseConfiguration(XNode?root)?{ ????????try?{ ????????????this.propertiesElement(root.evalNode("properties")); ????????????Properties?settings?=?this.settingsAsProperties(root.evalNode("settings")); ????????????this.loadCustomVfs(settings); ????????????this.loadCustomLogImpl(settings); ????????????this.typeAliasesElement(root.evalNode("typeAliases")); ????????????this.pluginElement(root.evalNode("plugins")); ????????????this.objectFactoryElement(root.evalNode("objectFactory")); ????????????this.objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); ????????????this.reflectorFactoryElement(root.evalNode("reflectorFactory")); ????????????this.settingsElement(settings); ????????????this.environmentsElement(root.evalNode("environments")); ????????????this.databaseIdProviderElement(root.evalNode("databaseIdProvider")); ????????????this.typeHandlerElement(root.evalNode("typeHandlers")); ????????????this.mapperElement(root.evalNode("mappers")); ????????}?catch?(Exception?var3)?{ ????????????throw?new?BuilderException("Error?parsing?SQL?Mapper?Configuration.?Cause:?"?+?var3,?var3); ????????} ????}
看到這是不是很熟悉了,這不就是mybatis-config.xml 配置文件里面的各個標簽名嘛,是的,這就是解析該文件,然后全部放在 configuration 對象中。需要注意的是,這里的 configuration 對象不僅包括 mybatis-config.xml 文件內容,也包括 xxxMapper.xml 文件內容。
⑤、build(configuration)
??public?SqlSessionFactory?build(Configuration?config)?{ ????return?new?DefaultSqlSessionFactory(config); ??}
就是去 new 了一個 DefaultSqlSessionFactory 對象,將 configuration 作為參數。
⑥、DefaultSqlSessionFactory(configuration)
????public?DefaultSqlSessionFactory(Configuration?configuration)?{ ????????this.configuration?=?configuration; ????}
3、總結
自此,SqlSessionFactory 的創(chuàng)建過程就講完了,總的來說就是一個封裝了配置文件的工廠類。那么得到了 SqlSessionFactory 這個工廠對象,接下來干嘛?生產 SqlSession,然后通過 SqlSession 進行數據庫的增刪改查操作
沒錯,接下來,指北君將給大家介紹 SqlSession 的交互過程,這也是 Mybatis 里面最重要的一個對象。
到此這篇關于詳解Mybatis核心類SqlSessionFactory的構建的文章就介紹到這了,更多相關Mybatis SqlSessionFactory內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- 解析Mybatis SqlSessionFactory初始化原理
- mybatis初始化SqlSessionFactory失敗的幾個原因分析
- MyBatis源碼解析——獲取SqlSessionFactory方式
- 使用Mybatis-Plus時的SqlSessionFactory問題及處理
- Mybatis SqlSessionFactory與SqlSession詳細講解
- Mybatis中自定義實例化SqlSessionFactoryBean問題
- MyBatis-plus報錯Property ‘sqlSessionFactory‘ or ‘sqlSessionTemplate‘ are required的解決方法
- 使用Mybatis時SqlSessionFactory對象總是報空指針
相關文章
springboot集成spring cache緩存示例代碼
本篇文章主要介紹了springboot集成spring cache示例代碼,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05Springboot重寫addInterceptors()方法配置攔截器實例
這篇文章主要介紹了Springboot重寫addInterceptors()方法配置攔截器實例,spring?boot拋棄了復雜的xml配置,我們可以自定義配置類(標注@Configuration注解的類)來實現WebMvcConfigurer接口,并重寫addInterceptors()方法來配置攔截器,需要的朋友可以參考下2023-09-09