分析源碼我們還是從編程式demo入手
我們通過建造者模式創建一個工廠類,配置文件的解析就是在這一步完成的,包括 mybatis-config.xml 和 Mapper 適配器文件。
- 首先進入build
- 進入XMLconfigBuilder–這裏就是配置文件創建的地方
- 可以看到這裏有很多解析文件的類
- 解析節點–這裏可以看出文件只解析了一次。
解析文件還是比較簡單的,基本上就是讀取文件的內容然後做存儲設置,我們來看看時序圖
DefaultSqlSession–最主要的就是創建了一個執行器
- 創建回話時拿到全局配置文件的配置,並且創建了事務工廠和創建執行器。
- 對執行器做判斷–兩次判斷的原因是因爲怕有人把默認執行器設置爲空–這裏也判斷了是否開啓了二級緩存的–這裏注意這個額插件調用方法先把他理解爲攔截器進行了一次包裝
- 我在baseExecutor裏面還看到了模板模式–把具體的增刪改查的方法都交給子類去做了
先看看繼承關係
看看時序圖
getMapper
- 爲什麼要引入mapper對象------爲了解決這種硬編碼的問題
一步步走
注意這個註冊器-點進去看
這裏的代碼就有點熟悉了吧。jdk的動態代理那麼作爲代理類一定有個規範,我們進去看
果然實現了invocationHandler
說明mapper對象是一個代理對象 - 爲什麼我們只需要mapper接口不需要去實現呢
目前來看,他的作用就是標識我們去找到對應的statementID找到sql語句他的功能也就完成了。
MapperProxy
- 既然是代理對象肯定會走到上圖中的invoke方法執行到mapperMethod.exeute中
爲什麼會判斷defaultMethod方法的原因是jdk1.8接口都是可以有defaultMethod方法的,這裏的這個cache是爲了提升獲取mapper的效率—這裏調用了一個computeIfAbsent map的方法構建本地緩存 - 判斷類型準備執行的語句類型
- 走到selectOne
爲什麼用list接收:我覺得這是一種比較前瞻的寫法吧,下面那個報錯應該都很熟悉,以前把查出來 的list用對象接收就是這個錯誤
- 這裏可以看到傳進來的是一個statementid的位置字符串,具體怎麼找到的就在MappedStatement這行代碼解決的。
- 走到query 的實現方法 --我們進入二級緩存這個實現方法
這裏的這個緩存key 就是判斷我們緩存是否命中的。判斷statementid和翻頁信息和sql是否一樣 - 繼續走query-他會有緩存走緩存沒緩存走查詢
這裏是判斷語句設置的一些參數做操作 - 走到queryFromDatabase --這樣就到了baseExecutor
- 接下來就是基本執行器的操作了
- 走到默認的simple執行器
在這裏感覺已經離真相越來越近了…這裏已經看到了jdbc 的statement了。 - 根據這個newStatementHandler進入–這裏就有我們熟悉的東西賦值了。
newParameterHandler 處理參數
newResultSetHandler 處理結果集
- 四大天王–能被插件攔截的四大天王
ParameterHandler,ResultSetHandler,StatementHandler,executor
- 然後對參數進行預編譯–然後執行查詢–這裏已經調用–然後處理結果集
已經調用ps.execute了這已經是jdbc的操作了