手撕JAVA(三十一)手撕Mybatis底層源碼

以上是一個標準的原生mybatis的工作流程,最關鍵的步驟是:

1.創建SqlSessionFactory

2.獲取SqlSession

3.獲取動態代理對象(mapperProxy)

3.執行方法

本文將按照以上一個mybatis的標準工作流程來拆解mybatis的底層源碼。

開始閱讀源碼之前,先建立三個概念,不然會對閱讀造成極大障礙:
1.mybatis有四大對象:executor、StatementHandler、ParamterHandler、ResultHandler

2.mybatis底層封裝的是JDBC,其實底層與數據庫交互的仍然是原生的JDBC

3.mybatis以xml配置文件來完成開發者與框架的交互,所以整個流程其實就是對配置文件的不斷解析與包裝。

1.創建SqlSessionFactory

返回一個DefaultSessionFactory,裏面包含一個configuration

創建SqlSessionFactory其實就是將xml中的配置文件解析出來,存入configuration類中去。

mybatis的xml配置文件有兩類:

1.全局配置文件:用來做全局配置

2.是mapper配置文件:用來寫SQL

具體過程就是調用各種解析器去解析這兩類xml中的標籤

configuration類中的屬性其實就是包含了配置文件中各種可能出現的標籤

configuration的成員變量中一個名叫mappedStatements的Map中以KV對的形式存放有mapper.xml的解析結果,key是sql標籤中的id值,value是MappedStatement對象

一個MappedStatement對象就是mapper.xml中一個sql標籤的解析結果。

獲取SqlSession

返回DefaultSqlSession,裏面包含configuration和executor

獲取SqlSession這其實就是根據configuration來創建executor

executor會在這一步被創建,並根據配置文件中的配置解析結果被層層包裝。

獲取mapperProxy

configuration中除了mappedStatement外還有個重要的屬性——mapperRegistry。

mapperRegistry中包含一切與mapper動態代理相關內容。其中的knowMappers屬性

是以KV對的形式存儲了每個mapper接口及其MapperProxyFactory。

mapperProxyFactory是用於生產代理對象的工廠類。

之所以每個mapper都會有單獨的一個mapperProxyFactory,而不使用一個總的工廠類來生產代理對象是因爲:

1.需要將xml中的sql標籤與mapper的方法做關聯。這樣才能實現在invoke接口的method的時候執行相應的sql標籤中的SQL內容。

2.兩者的映射關係存放在mapperProxyFactory中的methodCache中。

3.具體封裝過程爲在mapperProxyinvoke方法中將method封裝爲一個新的cacheMethod類放入mapperProxyFactorycacheMethod中。

備註:其實cacheMethod類中有三個屬性:1.接口 2.

mapperProxyFactory的源碼:

封裝兩個屬性:

  1. 對應mapper接口
  2. mapper接口方法和xml文件SQL標籤的映射關係map

mapperProxy的源碼:

執行方法

總體流程

executor負責執行、其實是調用的statementHandler

statementHandler負責預編譯、參數處理,其實是調用的ParamterHandler和ResultsetHandler

ParamterHandler負責參數處理、ResultsetHandler負責JAVA類與數據庫類之間的映射。     

詳細流程

1.調用代理對象方法,

首先在mapperProxy中將所調用方法封裝爲cacheMapperMethod對象。改對象中包含

應接口的引用、當前所調用方法的引用、configuration以及sqlSession的引用。

2.交給executor執行:

代理對象又調用sqlSession中的executor去執行。在執行前會先通過method名字去configuration中拿到對應的MappedStatement.MappedStatement中包含xml中一個SQL標籤的全部信息。然後會處理參數調用之前看過的參數處理流程的源碼,單個(包括單實體類)就返回,多個就封裝爲map。

3.判斷緩存

在真正執行之前還會判斷本次查詢在緩存中是否存在。存在的話直接去緩存中拿,不存在的話executor再繼續往下執行。

4.底層調用JDBC

最後executor底層其實就是封裝的原生JDBC的statement等組件。

流程總結

1.將配置文件解析爲Configuration對象,創建一個DefaultSqlSessionFactory對象

      裏面包含Configuration

2.創建一個DefaultSqlSession對象

      裏面包含Configuration、executor

      1.拿到Mapper接口對應的MapperProxy

      2.執行增刪改查方法

調用DefaultSqlSession來執行

         DefaultSqlSession調用自己裏面的executor來執行

                  創建Statementhandler、ParameterHandler、ResultHandler

                          Statementhandler負責預編譯,

                 statementhandler調用ParameterHandler來設置參數、

                 調用ResultHandler來封裝結果(做數據庫與JAVABean的映射)

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章