以上是一個標準的原生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.具體封裝過程爲在mapperProxy的invoke方法中將method封裝爲一個新的cacheMethod類放入mapperProxyFactory的cacheMethod中。
備註:其實cacheMethod類中有三個屬性:1.接口 2.
mapperProxyFactory的源碼:
封裝兩個屬性:
- 對應mapper接口
- 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的映射)