前面的獲取對象的過程基本都debug完了痘昌,下面看最后一行:
String name = mapper.selectNameById(1);
也就是執(zhí)行SQL語句的具體過程。
下面從SQL語句的執(zhí)行開始debug:
1入偷、String name = mapper.selectNameById(1);
我們自定義的接口UserMapper是個接口,沒有實(shí)現(xiàn)類脖岛,前面分析獲取mapper時我們知道隧出,mybatis會為mapper類生成代理類,生成代理類的方法是使用MapperProxyFactory工廠類生成,代理的類其實(shí)就是MapperProxy宿饱,所以我們要看下一步的執(zhí)行過程就要進(jìn)入這個類進(jìn)行查看熏瞄,
1、String name = mapper.selectNameById(1);
2谬以、org.apache.ibatis.binding.MapperProxy#invoke
其中第一個if判斷?if (Object.class.equals(method.getDeclaringClass()))? 强饮,這個MapperProxy就是一個InvocationHandler(他的作用是jdk創(chuàng)建動態(tài)代理時用的,沒印象的可以復(fù)習(xí)一下)为黎,也就是我們會根據(jù)當(dāng)前的接口創(chuàng)建一個這個接口的動態(tài)代理對象邮丰,使用動態(tài)代理對象再利用反射調(diào)用實(shí)際對象的目標(biāo)方法。
然而動態(tài)代理對象里面的方法都是Interface規(guī)定的铭乾。但是動態(tài)代理對象也能調(diào)用比如toString(),hashCode()等這些方法呀剪廉,這些方法是所有類從Object繼承過來的。
所以這個判斷的根本作用就是炕檩,如果利用動態(tài)代理對象調(diào)用的是toString斗蒋,hashCode,getClass等這些從Object類繼承過來的方法,就直接反射調(diào)用笛质。如果調(diào)用的是接口規(guī)定的方法泉沾。我們就用MapperMethod來執(zhí)行。所以這個判斷是十分必要的妇押。
繼續(xù)看下面的方法爆哑,判斷出不是Object的方法,是接口的方法舆吮,所以執(zhí)行下面的代碼揭朝,從cachedMapperMethod中獲取要執(zhí)行的方法:
1、String name = mapper.selectNameById(1);
2色冀、org.apache.ibatis.binding.MapperProxy#invoke
3潭袱、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
這是個典型的從緩存中獲取方法對象的代碼,如果緩存中沒有锋恬,就新建并加入緩存屯换,最后返回這個方法,methodCache對象是一個map与学,存儲了創(chuàng)建過的方法對象彤悔,創(chuàng)建的方式是根據(jù)接口,方法和配置對象進(jìn)行創(chuàng)建索守。到這里我們就獲取了我們實(shí)際要執(zhí)行的方法的對象了晕窑。
現(xiàn)在我們回來繼續(xù)看第二步,回到org.apache.ibatis.binding.MapperProxy#invoke方法中卵佛,
最后一行代碼return中執(zhí)行的杨赤,就是真正操作數(shù)據(jù)庫的方法敞斋。我們繼續(xù)看下一步:
1、String name = mapper.selectNameById(1);
2疾牲、org.apache.ibatis.binding.MapperProxy#invoke
3植捎、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4、org.apache.ibatis.binding.MapperMethod#execute
進(jìn)入這個方法可以看到阳柔,內(nèi)容很豐富焰枢,開始是一個判斷語句塊,判斷當(dāng)前的操作是什么類型舌剂,我們通過idea來看一下正在執(zhí)行的是什么類型:
如果是增刪改的話济锄,執(zhí)行方式比較一致和簡單,
準(zhǔn)備好參數(shù)然后去執(zhí)行架诞,本次執(zhí)行的是查詢操作拟淮,所以我們主要看下面的SELECT:
查詢操作通過判斷返回的類型,執(zhí)行對應(yīng)的方法谴忧,前面幾種是比較經(jīng)典的返回類型很泊,如果都不滿足,就會執(zhí)行else內(nèi)的方法沾谓,本次的selectNameById方法執(zhí)行的就是else中的內(nèi)容:
第一行是轉(zhuǎn)換參數(shù)為SQL命令中的形式委造,下面這一行是關(guān)鍵,真正執(zhí)行的是sqlSession.selectOne方法均驶,我們在前面討論獲取sqlSession對象的源碼的時候昏兆,查看了SqlSession類中的方法,這是其中一個妇穴。傳入的第一個參數(shù)就是方法:
第二個就是參數(shù)爬虱,下面我進(jìn)入這個方法,查看流程:
1腾它、String name = mapper.selectNameById(1);
2跑筝、org.apache.ibatis.binding.MapperProxy#invoke
3、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4瞒滴、org.apache.ibatis.binding.MapperMethod#execute
5曲梗、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
我們在使用mybatis的時候,用的是官方文檔建議的方法妓忍,獲取mapper對象虏两,使用mapper對象執(zhí)行我們自定義的數(shù)據(jù)庫操作方法。官方文檔上還有另一種調(diào)用方法:
就是直接調(diào)用sqlSession中的方法世剖,上面圖片例子中的兩個參數(shù)就是我們前面的過程在組合的參數(shù)定罢,也就是說獲取mapper對象執(zhí)行方法最終的過程也是執(zhí)行sqlSession中的內(nèi)容,和上面這種方法殊途同歸搁廓。我們繼續(xù)來看selectOne中的內(nèi)容引颈,selectOne最終的執(zhí)行過程也是執(zhí)行selectList查詢一個列表耕皮,然后獲取列表中的第一個元素境蜕,繼續(xù)看selectList方法:
1蝙场、String name = mapper.selectNameById(1);
2勇皇、org.apache.ibatis.binding.MapperProxy#invoke
3慨仿、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4钦睡、org.apache.ibatis.binding.MapperMethod#execute
5贺氓、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6叉瘩、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
這里加了一個方法參數(shù)聊品,RowBounds.DEFAULT鹿霸,這是物理分頁傳入的默認(rèn)參數(shù)宽闲,返回的結(jié)果其實(shí)分頁了拉队,但是和沒分頁效果一樣弊知,下面繼續(xù)調(diào)用:
1、String name = mapper.selectNameById(1);
2粱快、org.apache.ibatis.binding.MapperProxy#invoke
3秩彤、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4、org.apache.ibatis.binding.MapperMethod#execute
5事哭、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6漫雷、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
我們在執(zhí)行jdbc的時候鳍咱,先編譯SQL語句降盹,獲取一個Statement對象,這里獲取的是一個MappedStatement對象谤辜,這個類對應(yīng)的就是select標(biāo)簽蓄坏。類的屬性和select標(biāo)簽的屬性一致。下面這一行executor.query方法執(zhí)行操作丑念,繼續(xù)看下面的代碼涡戳,使用Executor的對象執(zhí)行,Executor是一個接口渠欺,有兩個實(shí)現(xiàn)類妹蔽,通過工具可以看到這里使用的是CachingExecutor類的對象實(shí)例執(zhí)行的:
1、String name = mapper.selectNameById(1);
2挠将、org.apache.ibatis.binding.MapperProxy#invoke
3胳岂、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4、org.apache.ibatis.binding.MapperMethod#execute
5舔稀、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6乳丰、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8内贮、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
通過類名我們可以猜測到产园,這個Executor執(zhí)行類是使用內(nèi)存的汞斧,將數(shù)據(jù)保存到緩存中,這樣可以有效的解決增刪改查性能什燕。緩存的作用域?yàn)閙apper(namespace)粘勒,所以同一個namespace的操作會影響到相同作用域下的緩存,這樣不同的域?qū)ν粋€表進(jìn)行操作很有可能導(dǎo)致緩存中的數(shù)據(jù)不一樣屎即,出現(xiàn)問題庙睡,還是不推薦使用。我們看方法的內(nèi)容:
前面兩行是創(chuàng)建緩存值技俐,獲取記錄乘陪,繼續(xù)往下看:
1、String name = mapper.selectNameById(1);
2雕擂、org.apache.ibatis.binding.MapperProxy#invoke
3啡邑、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4、org.apache.ibatis.binding.MapperMethod#execute
5井赌、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6谤逼、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8族展、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
9森缠、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
上面這個過程就是一級緩存的內(nèi)容,如果緩存里不為空仪缸,就從緩存中查詢贵涵,如果緩存為空,就查詢數(shù)據(jù)庫恰画,這里啟動程序只進(jìn)行一次查詢宾茂,所以會走查詢數(shù)據(jù)庫的分支,最后一行的delegate對象拴还,也是一個Executor對象跨晴,這里走不使用緩存的分支,執(zhí)行操作使用的BaseExecutor對象:
1片林、String name = mapper.selectNameById(1);
2端盆、org.apache.ibatis.binding.MapperProxy#invoke
3、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4费封、org.apache.ibatis.binding.MapperMethod#execute
5焕妙、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7弓摘、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8焚鹊、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
9、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
10韧献、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
這里從數(shù)據(jù)庫查末患,走的是:
list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
這條代碼分支研叫,從名字可以看出從數(shù)據(jù)庫查詢,參數(shù)中傳了很多璧针,除了編譯好的SQL嚷炉,還有分頁,結(jié)果的handler陈莽,等等渤昌,這些是mybatis封裝jdbc后以自己的特色去執(zhí)行SQL的方式虽抄,這種麻煩的方法簡化了我們使用mybatis的方式走搁,下面繼續(xù)看:
1、String name = mapper.selectNameById(1);
2迈窟、org.apache.ibatis.binding.MapperProxy#invoke
3私植、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4、org.apache.ibatis.binding.MapperMethod#execute
5车酣、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6曲稼、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8湖员、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
9贫悄、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
10、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
11娘摔、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
看代碼:
localCache.putObject(key, EXECUTION_PLACEHOLDER);
這里查詢了一次以后窄坦,加入了一級緩存當(dāng)中,下面就是執(zhí)行doQuery方法:
1凳寺、String name = mapper.selectNameById(1);
2鸭津、org.apache.ibatis.binding.MapperProxy#invoke
3、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4肠缨、org.apache.ibatis.binding.MapperMethod#execute
5逆趋、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7晒奕、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8闻书、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
9、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
10脑慧、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
11魄眉、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
12、org.apache.ibatis.executor.SimpleExecutor#doQuery
這里進(jìn)入了SimpleExecutor類中漾橙,第一行的Statement stmt =null;代碼有點(diǎn)眼熟杆融,就是我們jdbc中的Statement 對象,說明我們馬上要接近真相了霜运!繼續(xù)脾歇,前面三個是對SQL語句進(jìn)行預(yù)編譯蒋腮,然后執(zhí)行query方法,通過debug藕各,知道下一步執(zhí)行這個方法:
1池摧、String name = mapper.selectNameById(1);
2、org.apache.ibatis.binding.MapperProxy#invoke
3激况、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4作彤、org.apache.ibatis.binding.MapperMethod#execute
5、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6乌逐、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7竭讳、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
9浙踢、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
10绢慢、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
11、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
12洛波、org.apache.ibatis.executor.SimpleExecutor#doQuery
13胰舆、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
這里就是一行調(diào)用,繼續(xù)debug:
1蹬挤、String name = mapper.selectNameById(1);
2缚窿、org.apache.ibatis.binding.MapperProxy#invoke
3、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4焰扳、org.apache.ibatis.binding.MapperMethod#execute
5倦零、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7蓝翰、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8光绕、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
9、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
10畜份、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
11诞帐、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
12、org.apache.ibatis.executor.SimpleExecutor#doQuery
13爆雹、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
14停蕉、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
第一行是jdk中jdbc的類,執(zhí)行獲取預(yù)編譯操作钙态,然后執(zhí)行了ps.execute();慧起,這個就是我們的jdbc方法!終于到這里了册倒!resultSetHandler是mybatis的對象蚓挤,包裝jdbc的結(jié)果,我們繼續(xù)看:
1、String name = mapper.selectNameById(1);
2灿意、org.apache.ibatis.binding.MapperProxy#invoke
3估灿、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4、org.apache.ibatis.binding.MapperMethod#execute
5缤剧、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6馅袁、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8荒辕、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
9汗销、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
10、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
11抵窒、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
12弛针、org.apache.ibatis.executor.SimpleExecutor#doQuery
13、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
14估脆、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
15钦奋、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleResultSets
ResultSetHandler負(fù)責(zé)處理兩件事,一是處理Statement執(zhí)行后產(chǎn)生的結(jié)果集疙赠,生成結(jié)果列表,二是處理存儲過程執(zhí)行后的輸出參數(shù)朦拖。DefaultResultSetHandler類是ResultSetHandler的默認(rèn)實(shí)現(xiàn)圃阳,這里執(zhí)行了這個類的handleResultSets方法,其實(shí)現(xiàn)的步驟就是將Statement執(zhí)行后的結(jié)果集璧帝,按照Mapper文件中配置的ResultType或ResultMap來封裝成對應(yīng)的對象捍岳,最后將封裝的對象返回即可,這里有一行代碼:
ResultSetWrapper rsw = getFirstResultSet(stmt);
我們進(jìn)入getFirstResultSet方法看一看:
這里的代碼很眼熟了睬隶,就是jdbc接收結(jié)果的過程锣夹,最后一行把這個結(jié)果封裝成了mybatis中的結(jié)果對象,封裝的過程如下:
這里面包含的記過的很多熟悉苏潜,類型银萍,名稱,對象的類型恤左,等等贴唇。我們繼續(xù)來看handleResultSets方法,組合好多個返回結(jié)果的list后飞袋,我們看最后一行代碼戳气,執(zhí)行collapseSingleResultList方法:
1、String name = mapper.selectNameById(1);
2巧鸭、org.apache.ibatis.binding.MapperProxy#invoke
3瓶您、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4、org.apache.ibatis.binding.MapperMethod#execute
5、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6呀袱、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7芯肤、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
9压鉴、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
10崖咨、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
11、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
12油吭、org.apache.ibatis.executor.SimpleExecutor#doQuery
13击蹲、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
14、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
15婉宰、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleResultSets
16歌豺、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#collapseSingleResultList
從判斷可以看出,在判斷是不是只有一條結(jié)果心包,這樣封裝返回結(jié)果的對象就執(zhí)行完了类咧。我們再次返回前面的方法:
1、String name = mapper.selectNameById(1);
2蟹腾、org.apache.ibatis.binding.MapperProxy#invoke
3痕惋、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4、org.apache.ibatis.binding.MapperMethod#execute
5娃殖、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6值戳、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8炉爆、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
9堕虹、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
10、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
11芬首、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
12赴捞、org.apache.ibatis.executor.SimpleExecutor#doQuery
13、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
14郁稍、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
15赦政、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleResultSets
16、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#collapseSingleResultList
17艺晴、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
這里是前面的方法昼钻,返回的就是符合類型的結(jié)果的list,無論一條還是多條封寞,繼續(xù)debug:
1然评、String name = mapper.selectNameById(1);
2、org.apache.ibatis.binding.MapperProxy#invoke
3狈究、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4碗淌、org.apache.ibatis.binding.MapperMethod#execute
5、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7亿眠、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8碎罚、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
9、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
10纳像、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
11荆烈、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
12、org.apache.ibatis.executor.SimpleExecutor#doQuery
13竟趾、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
14憔购、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
15、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleResultSets
16岔帽、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#collapseSingleResultList
17玫鸟、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
18、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
繼續(xù)往回執(zhí)行:
1犀勒、String name = mapper.selectNameById(1);
2屎飘、org.apache.ibatis.binding.MapperProxy#invoke
3、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4贾费、org.apache.ibatis.binding.MapperMethod#execute
5钦购、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7铸本、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8肮雨、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
9、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
10箱玷、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
11、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
12陌宿、org.apache.ibatis.executor.SimpleExecutor#doQuery
13锡足、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
14、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
15壳坪、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleResultSets
16舶得、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#collapseSingleResultList
17、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
18爽蝴、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
19沐批、org.apache.ibatis.executor.SimpleExecutor#doQuery
繼續(xù)往回執(zhí)行:
1、String name = mapper.selectNameById(1);
2蝎亚、org.apache.ibatis.binding.MapperProxy#invoke
3九孩、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4、org.apache.ibatis.binding.MapperMethod#execute
5发框、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6躺彬、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
9宪拥、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
10仿野、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
11、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
12她君、org.apache.ibatis.executor.SimpleExecutor#doQuery
13脚作、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
14、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
15缔刹、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleResultSets
16球涛、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#collapseSingleResultList
17、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
18桨螺、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
19宾符、org.apache.ibatis.executor.SimpleExecutor#doQuery
20、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
這里把最終的查詢結(jié)果放到了一級緩存中灭翔,然后繼續(xù)往回執(zhí)行:
1魏烫、String name = mapper.selectNameById(1);
2、org.apache.ibatis.binding.MapperProxy#invoke
3肝箱、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4哄褒、org.apache.ibatis.binding.MapperMethod#execute
5、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6煌张、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7呐赡、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
9骏融、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
10链嘀、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
11、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
12档玻、org.apache.ibatis.executor.SimpleExecutor#doQuery
13怀泊、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
14、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
15误趴、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleResultSets
16霹琼、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#collapseSingleResultList
17、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
18凉当、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
19枣申、org.apache.ibatis.executor.SimpleExecutor#doQuery
20、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
21看杭、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
這里面對緩存最后進(jìn)行處理忠藤,繼續(xù)往回看:
1、String name = mapper.selectNameById(1);
2泊窘、org.apache.ibatis.binding.MapperProxy#invoke
3熄驼、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4像寒、org.apache.ibatis.binding.MapperMethod#execute
5、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6瓜贾、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7诺祸、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
9祭芦、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
10筷笨、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
11、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
12龟劲、org.apache.ibatis.executor.SimpleExecutor#doQuery
13胃夏、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
14、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
15昌跌、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleResultSets
16仰禀、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#collapseSingleResultList
17、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
18蚕愤、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
19答恶、org.apache.ibatis.executor.SimpleExecutor#doQuery
20、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
21萍诱、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
22悬嗓、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
23、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
24裕坊、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
25包竹、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
26、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
最后帶著list回到了selectOne這里籍凝,
查詢成功以后周瞎,返回了第一個對象,下面是代理對象:
1饵蒂、String name = mapper.selectNameById(1);
2堰氓、org.apache.ibatis.binding.MapperProxy#invoke
3、org.apache.ibatis.binding.MapperProxy#cachedMapperMethod
4苹享、org.apache.ibatis.binding.MapperMethod#execute
5、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
6浴麻、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
7得问、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
8敦跌、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)
9旧乞、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
10、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
11万俗、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
12膏萧、org.apache.ibatis.executor.SimpleExecutor#doQuery
13漓骚、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
14蝌衔、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
15、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#handleResultSets
16蝌蹂、org.apache.ibatis.executor.resultset.DefaultResultSetHandler#collapseSingleResultList
17噩斟、org.apache.ibatis.executor.statement.PreparedStatementHandler#query
18、org.apache.ibatis.executor.statement.RoutingStatementHandler#query
19孤个、org.apache.ibatis.executor.SimpleExecutor#doQuery
20剃允、org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
21、org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
22齐鲤、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql)
23斥废、org.apache.ibatis.executor.CachingExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)?
24、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object, org.apache.ibatis.session.RowBounds)
25给郊、org.apache.ibatis.session.defaults.DefaultSqlSession#selectList(java.lang.String, java.lang.Object)
26牡肉、org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne(java.lang.String, java.lang.Object)
27、org.apache.ibatis.binding.MapperMethod#execute
28淆九、org.apache.ibatis.binding.MapperProxy#invoke
29统锤、String name = mapper.selectNameById(1);
最終我們回到了調(diào)用的地方,返回了查詢的name吩屹!
總結(jié)
來總結(jié)一下跪另,通過debug看源碼是一個不太會看源碼的人的一個不錯的方法,我們上面通過debug來查看了mybatis查詢的整個過程煤搜,中間的一級緩存免绿,涉及到的幾種查詢Executor,獲取返回結(jié)果的ResultSetHandler擦盾,編譯的StatementHandler嘲驾,物理分頁的RowBounds等等幾個對象是如果對jdbc查詢的整個過程進(jìn)行潤色的,查詢的整個過程在這個源碼分析中是最復(fù)雜的迹卢,正是由于這個復(fù)雜辽故,我們才能輕松的使用mybatis!