前言

這個分類比較連續(xù),如果這里看不懂,或者第一次看,請回顧之前的博客

http://www.cnblogs.com/linkstar/category/1027239.html

經(jīng)過之前的學習我們知道了工廠是如何建立的,是如何生產(chǎn)產(chǎn)品的。

那么今天要進入重點中的重點了。那就是我們究竟是如何使用這個產(chǎn)品的。

也就是SqlSeesion究竟是如何運行的,內(nèi)部究竟有些什么東西。

這部分很難,需要使用到我們之前的基礎裝備哦。

 

產(chǎn)品運行的大致步驟

我們還是老規(guī)矩從外部來看看是如何運行的。

SqlSession session = sqlSessionFactory.openSession();Demo demo = (Demo) session.selectOne("com.xex.dao.mapper.DemoMapper.selectDemo");session.close();從外部看,最簡單的情況就是這樣,看起來比較簡單。1、從工廠獲取產(chǎn)品(獲取產(chǎn)品已經(jīng)在上節(jié)提到,這里就不多說了)2、執(zhí)行需要的sql方法(重點)3、關閉產(chǎn)品(回收產(chǎn)品) 

產(chǎn)品運行的內(nèi)部過程

從大致的步驟我們可以看出重點就在第二步上面了。怎么隨便調(diào)用一個方法就能執(zhí)行sql了呢?過程復雜,我盡量講的仔細一些。我們就以這個查詢來作為例子。 首先我們進入selectOne方法里面看看。(idea使用快捷鍵Ctrl+Alt+B查看光標上的方法的實現(xiàn))


我們需要查看的是DefaultSqlSession的實現(xiàn),至于為什么之前已經(jīng)講過咯。

大學生就業(yè)培訓,高中生培訓,在職人員轉行培訓,企業(yè)團訓

留意一個地方,我們傳入的參數(shù)statement="com.xex.dao.mapper.DemoMapper.selectDemo"

大學生就業(yè)培訓,高中生培訓,在職人員轉行培訓,企業(yè)團訓

從大方向上看,傳入的參數(shù)是“com.xex.dao.mapper.DemoMapper.selectDemo”,返回的參數(shù)是一個類MappedStatement

大學生就業(yè)培訓,高中生培訓,在職人員轉行培訓,企業(yè)團訓

 

mappedStatements簡述

這里用文字來敘述一下這個mappedStatements的構建思路。因為具體細節(jié)太多,就不一一截圖說明了,就截圖重點部分了,希望你能跟上并按照思路去源碼中尋找。

但是這個類里面一些細節(jié)值得我們學習和研究,所以很值得看看。

1、首先這mappedStatements是我們熟悉的Configuration類中的一個變量。

2、是這樣被new出來的:new StrictMap

3、StrictMap是Configuration中的一個內(nèi)部類繼承自HashMap,與之不同的是的,這個map有個名字name的變量,然后主要不同在于這個map的put和get方法。

4、put方法中:

大學生就業(yè)培訓,高中生培訓,在職人員轉行培訓,企業(yè)團訓

下面有這么幾句話是用來描述這個put方法的,看完之后仔細思考,這三條是怎么總結出來的。

一、這個map會把com.xex.dao.mapper.DemoMapper.selectDemo這種包名按照“.”拆分后取出最后一個元素,這里就是selectDemo。(只是舉例)

二、這個map的值都是String,如果在put的時候發(fā)現(xiàn)有相同的key,那么不會馬上拋出異常,而是覆蓋了重復的鍵,把重復鍵的值修改成了Ambiguity類型。

三、Ambiguity這個類其實就是一個字符串。

首先對于第一條,因為拆分之后最后的selectDemo是我們寫的一條條sql語句的id,mybatis是通過這個id去尋找需要運行那一條數(shù)據(jù)庫語句的,所以這個必須唯一。而存放的時候只需要最后的selectDemo就可以了。

那么就奇怪了,為什么mybatis遇到相同的鍵也就是有兩條sql語句有相同的id時沒有直接選擇在加載配置的時候就拋出異常而是存放了一個奇怪的Ambiguity類型呢?(Ambiguity的意思是含糊的,不明確的)

讓我們來看看get方法應該就明白了。

大學生就業(yè)培訓,高中生培訓,在職人員轉行培訓,企業(yè)團訓

一、調(diào)用父類的get也就是HashMap的get方法。

二、空值拋異常

三、Ambiguity拋異常

聰明的你應該已經(jīng)明白了。

給笨笨的你解釋一下,空值拋異常就是通過這個id找不到對應的需要執(zhí)行的sql語句當然就異常了;當Ambiguity拋異常就表面有兩個id相同的sql語句,mybatis不知道要執(zhí)行哪一個了,所以異常了。

剩下的就是這個map是什么時候建立的呢?當然是一開始建造工廠的時候咯,之前有講過,不明白可以翻翻前面的,復習一下咯。

具體在MappedStatement里面sql是怎么存放的,有興趣的可以直接進這個類看看。這里我們就講到這里了,要繼續(xù)主進程了。

 

sql的執(zhí)行

我們繼續(xù)來接著之前的來看,獲得了sql之后怎么執(zhí)行的呢?

return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);

首先是誰去執(zhí)行的?一個叫做executor的東西。

我們叫它執(zhí)行者。它是一個接口。然后在產(chǎn)品生產(chǎn)的時候就被賦值了。

然后是它去執(zhí)行的query方法,返回值是一個泛型約束的List。

 

然后我們來看參數(shù):

1、ms是我們剛才獲得的執(zhí)行語句。

2、wrapCollection是將當前的參數(shù),也就是數(shù)據(jù)庫查詢的時候的入?yún)?,比如查詢條件,如果查詢條件是集合(Collection)或者數(shù)組(Array)形式的話轉換成map,如果不是就直接返回。

我們現(xiàn)在沒有入?yún)?,所以返回的是個null

3、rowBounds   mybatis的分頁功能,我們不管他

4、Executor.NO_RESULT_HANDLER

是個null,叫做沒有結果的處理器

 

然后我們來看看執(zhí)行

大學生就業(yè)培訓,高中生培訓,在職人員轉行培訓,企業(yè)團訓

大學生就業(yè)培訓,高中生培訓,在職人員轉行培訓,企業(yè)團訓

 

下面就是關鍵了?。。∽⒁饪?/span>

大學生就業(yè)培訓,高中生培訓,在職人員轉行培訓,企業(yè)團訓

從緩存中拿我們就不看了,比較簡單,緩存其實是個map嘛

我們就看從數(shù)據(jù)庫查詢

大學生就業(yè)培訓,高中生培訓,在職人員轉行培訓,企業(yè)團訓

 

大學生就業(yè)培訓,高中生培訓,在職人員轉行培訓,企業(yè)團訓

下面走這個

大學生就業(yè)培訓,高中生培訓,在職人員轉行培訓,企業(yè)團訓

大學生就業(yè)培訓,高中生培訓,在職人員轉行培訓,企業(yè)團訓

看到這里的excute沒有,這里就是真正的執(zhí)行sql了,里面呢就是傳說中的jdbc了,喜歡你就進去看看,不喜歡我們繼續(xù)看看結果集最后是如何映射的。

 

對返回結果的處理

大學生就業(yè)培訓,高中生培訓,在職人員轉行培訓,企業(yè)團訓

 

 

至此整個sql在mybatis中的執(zhí)行過程終于是完成了。

整條路線如果仔細來看真的很長,不得不佩服設計者如此縝密的設計。

 

總結

我們經(jīng)過整個路線的行走,我們已經(jīng)明確了sql在mybatis中執(zhí)行的全部過程。

相信你也有所收獲,其實我們應該多想想設計者為何這樣設計,有的代碼為什么要這樣寫。這樣寫的好處和設計思路又是什么。有什么樣的優(yōu)化或者優(yōu)點值得我們學習。

不過不要高興的太早。

這還沒完呢!

我們的裝備到現(xiàn)在還沒用上呢!后面一篇就會講解,為什么只需要定義一個接口在mybatis中就能起作用,不需要實現(xiàn)類。

代理模式在其中的運用以及反射的強大。

希望上面的思路對你看源碼有幫助。如有問題還請多多提出,不勝感激。

轉載請注明出處:http://www.cnblogs.com/linkstar/category/1027239.html

http://www.cnblogs.com/linkstar/p/7182695.html