1. 程式人生 > >《MyBatis技術內幕》筆記2—核心處理層

《MyBatis技術內幕》筆記2—核心處理層

        因為該文主要是看書的筆記(當然自己看書時也會看原始碼並跟蹤除錯),所有沒有詳實的原始碼分析,但是可以作為原始碼分析的流程、索引和註釋。

二、核心處理層

1、Mybatis初始化     Mybatis初始化過程中,除了會讀取mybatis-config.xml配置檔案以及對映配置檔案,還會載入配置檔案指定的類,處理類中的註解,建立一些配置物件,最終完成框架中各個模組的初始化。 相關模式:建造者模式。 SqlSessionFactoryBuilder.build():初始化入口,會建立XMLConfigBuilder(繼承BaseBuilder),包含了Configuration(幾乎全部的配置資訊)、typeAliasRegistry(定義的別名)、typeHandlerRegistry(自定義的jdbc型別與java型別的轉換)。 XMLConfigBuilder.parse():解析mybatis-config.xml配置檔案的入口,在裡面解析到mappers標籤時就會去載入一個個mapper.xml並解析。 XMLMapperBuilder.parse():解析mapper.xml對映檔案的入口,完成名稱空間與mapper介面繫結、解析ResultMap等,在解析sql節點時會交由XMLStatementBuilder負責。由於解析一個節點時會引用後面還未解析的節點,所以解析主要分兩次,第一次解析configurationElement()會根據未解析的引用建立不同的*Resolver,並新增到Configuration的不同incomplete*集合中,然後第二次解析就是處理不同incomplete*,最後完成解析。 XMLStatementBuilder.parseStatementNode():是解析sql節點的入口,最後會被解析成MappedStatement物件。

2、SQL解析SqlSource與SqlNode 相關模式:組合模式。 OGNL表示式:用於方便獲取${物件.屬性}、標籤中"屬性!=null"等裡面的表示式對應的值,在SqlNode中就會使用Ognl獲得對應實參的值。 SqlSource介面:sql節點中的sql語句會被解析成對應的SqlSource物件,當然SqlSource物件是存在MappedStatement物件中的。在呼叫執行mapper介面時,會根據全域性的配置、傳入的引數獲得帶?的實際sql(即確定了<if>等節點的文字)和引數集(按?順序對應),這裡還沒有把實參繫結到sql語句上。 SqlNode介面:sql語句中的定義的動態sql節點、文字節點等又會被解析成不同的SqlNode物件,使用組合模式組合成一個SqlNode,當然SqlNode物件是存在SqlSource中的。 DynamicSqlSource:實現SqlSource介面,負責處理動態語句,包括一個全域性配置Configuration和SqlNode。其中SqlNode的實現是MixedSqlNode。 RawSqlSource:實現SqlSource介面,負責處理靜態語句,只包含一個SqlSource。 StaticSqlSource:實現SqlSource介面,DynamicSqlSource和RawSqlSource最終都會將處理後的sql語句封裝成StaticSqlSource物件。包含Configuration、parameterMappings和sql字串(例如insert into tableName (column1,column2,column3) values (?,?,?))。 MixedSqlNode:實現SqlNode介面,由多個SqlNode的組合。如果sql語句中有if標籤,那麼MixedSqlNode中就含有IfSqlNode,如果有foreach標籤,那麼就含有ForEachSqlNode,其它文字語句就對應StaticTextSqlNode。

3、結果集對映ResultSetHandler ResultSetHandler介面:負責對映select語句查詢得到的結果集,還會處理儲存過程執行後的輸出引數。使用者可以實現該介面,自定義處理結果集。 ResultSetHandler.handleResultSets():處理結果集入口,生成相應的結果物件集合。主要分兩次處理,第一次處理MappedStatement.resultMaps中對應的結果集,如果處理中發現某個屬性(結果集中的巢狀對映)涉及未解析的結果集,則把對應的ResultMapping放入nextResultMaps中,第二次處理就是根據nextResultMaps處理巢狀對映,完善結果集。 ResultSetHandler.handleRowValuesForSimpleResultMap():對於非巢狀的簡單對映最終會由該方法處理,包括定位到指定的結果行、檢測處理行數超限制和是否還有要處理的結果行、解決discriminate標籤得到最終resultMap對映、執行對映得到結果物件(這裡就會處理巢狀)、儲存結果物件。 ResultSetHandler.handleRowValuesForNestedResultMap():對於巢狀對映最終會由該方法處理。 上面的巢狀可能說的有問題,巢狀的處理個人覺得太複雜,但平時基本沒用巢狀,所以沒有繼續深究。

4、SQL執行Executor與StatementHandler 相關模式:模板方法模式、裝飾器模式。 Executor介面:是mybatis核心介面之一,其中定義了資料庫操作的基本方法(最終由StatementHandler執行),這些方法有些執行步驟是相同的,所以可以使用模板方法模式。 BaseExecutor抽象類:實現了Executor介面,實現了大部分方法,其中就使用了模板方法模式,它主要提供了快取管理和事務管理的基本功能。繼承BaseExecutor的子類只需要實現四個基本方法來完成資料庫的相關操作即可。 一級快取:BaseExecutor中提供的快取是一級快取,是會話級別的快取。 CachingExecutor:是一個Executor裝飾器,它為Executor物件增加了二級快取的相關功能。 二級快取:是應用級別的快取,可在mybatis-config.xml檔案中配置。 StatementHandler介面:是mybatis核心介面之一,完成了最核心的工作,如建立Statement物件、為sql語句繫結實參、執行sql語句、將結果集對映成結果物件。 ParameterHandler介面:DefaultParameterHandler實現類,完成sql語句與實參的繫結。