一個例子教你看源碼!深入淺出教你理解Template中的query和queryForObject的區別!

一. 前言

最近在搞一個servlet+jsp+el表達式+jstl+mysql+mvc的綜合性小項目。

遇到了一個問題:Template中的query和queryForObject到底有什麼區別呢?因爲有時候用query,有時候用queryForObject,實在是玄乎。搜索大量的資料,並沒有我想要的答案。

我想知道:是不是  queryForObject(String sql, RowMapper<T> rowMapper, Object... args)  只返回一條記錄,而

query(String sql, RowMapper<T> rowMapper)  可以返回一組記錄?爲什麼有這個疑問呢?因爲我遇到過這種用法,如下圖:

這裏 query 查詢後直接把數據封裝成User對象並以 List<User> 的方式返回 而 queryForObject 卻只返回了一個User對象。那麼是不是隻要是這種形式的的 query 和 queryForObject 就都會分別返回 List<User> 和 一個User對象 ?我不確定,但是網上又找不到我想要的答案。無奈之下,我開始了我的第一次深入理解源碼之旅。

二. 查看源碼 + 深度剖析

1.queryForObject

首先,我按ctrl+左鍵點擊 queryForObject 進入源碼

我們需要分析的是這個方法的源碼。(這裏聲明一下,返回值其實已經可以解決我的問題了,但是爲了學會剖析源碼的方法,就當我們不知道這個返回值。。。

       可以看到他用 List<T> results 來存儲了查詢的結果,但是並不是直接返回了,從他拋出異常和她返回的方法可以看出,是爲了保證數據的安全性才這麼做的,如果返回數據不符合規定就拋出異常,而不是直接返回被輕易取出不符合規定的數據。再往下看 return 語句,這個方法一般人應該不知道是啥,沒關係,繼續看他的源碼。

       首先他用size存儲按 sql語句 從數據庫中返回的結果集 results,如果 結果集爲 null,size就爲0。否則 size 就爲結果集長度。

然後判斷 size :

      1. ==0:拋出空結果集異常。

      2. >1:拋出不正確的結果集長度異常

      3. ==1:因爲返回結果集不可能爲負數,所以else判斷的肯定是size==1的情況。這時候返回結果集的迭代器的next(),即                        讓迭代器的指針指向下一位。

*  當創建完成指向某個集合或者容器的Iterator對象是,這是的指針其實指向的是第一個元素的上方,即指向一個空


     到這裏,我們就知道了一個既定事實,他返回的長度必定爲1,也就是說:queryForObject 只返回了一個User對象,如果長度不是1就會拋出異常。

回過頭來看上一層源碼,我們就可以輕易的明白他爲什麼要在return時先調用方法:


 

其實就是爲了

      1. 保證返回的數據只有一條:比如這裏是查詢User對象的方法,那麼該方法就只會返回一個封裝好的User對象  。

      2. 將迭代器的指針往下移一位 :方便用戶去取數據                                                                                                                        


2.query 

這個比較簡單一點,我們可以很清楚的看到他返回一個List集合,並且return也是直接return了。 

三. 結語

至此,查看源碼+深度剖析就完成了,同時也解決了我的疑惑。在這裏建議大家學會去看源碼,

有時候比上網去查資料還要快。

同時也能夠提升你的代碼閱讀能力和理解能力

還能夠讓你感受到代碼之美,讓你以後以更加優雅的方式去寫代碼!

不行了,實在編不下去了,蛤蛤蛤~

以後遇到有深度的問題還會記錄一些深度剖析源碼的例子!

我是一個小coder,希望和努力的大家一起前行,加油 ~                                                        

 

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