Spring源碼之JdbcTemplate中的坑,你中招了嗎

編程語言 MySQL Java 腳本語言 開發技術專注者 2017-05-31

我上篇文章分析了JdbcTemplate中各種回調類的使用,但是,我們平常用JdbcTemplate最多的還是query()方法和queryForObject()方法。同樣,其中還有一個使用最多的是BeanPropertyRowMapper。

但是,在JdbcTemplate.queryForObject()中有一個很不起眼的坑,BeanPropertyRowMapper中也一樣。

坑一:BeanPropertyRowMapper的mapRow()

我們在使用BeanPropertyRowMapper時,是給query()方法傳遞一個BeanPropertyRowMapper對象,讓JdbcTemplate幫我們把查詢結果集ResultSet的每一行結果都使用BeanPropertyRowMapper.mapRow()方法,轉化成我們想要的Java類對象。從BeanPropertyRowMapper名稱上也能夠看出來,它是用來映射Java對象的屬性和MySQL表的字段名稱的。但是,在映射的過程中,如果不注意Java對象的屬性名的規範,很可能就得不到我們想要的結果。

先來看一下,在創建BeanPropertyRowMapper對象時,會調用其中的initialize方法,我們看一下initialize方法的具體實現。

Spring源碼之JdbcTemplate中的坑,你中招了嗎

BeanPropertyRowMapper中的initialize方法

如圖,

首選,說一下mappedFields,mapperFields是一個HashMap,用來匹配Java對象的屬性和MySQL表的字段名的。mapperFields中存放所有可能與MySQL表的字段名映射上的那些Java屬性名字。

如紅色框框的第一行,在initialize方法中,BeanPropertyRowMapper會把傳入的泛型Java類的所有屬性名稱的全小寫形式放入mapperFields中,

第二行,把Java類的屬性名轉化成下劃線分割的形式,如myName會被轉化成my_name,這是因為,數據庫在設計字段名稱的時候,一般都會使用下劃線分割形式,也就是my_name。

重點(敲黑板)

所以,如果在使用時,Java類名稱要想和數據庫字段名稱匹配上,必須要把數據庫字段名稱設計成以下兩種中的一種,

  1. 數據庫字段名設計成全小寫的形式,如myname;

  2. 數據庫字段名設計成下劃線分割的形式,如my_name;

同時,Java屬性名稱應該儘量遵循Java編碼風格,使用camelCase風格,如myName。

坑二:JdbcTemplate.queryForObject()

在使用queryForObject()方法時,我們一般是希望返回一個對象,而不是像query()方法一樣返回一個列表。

但是,如果ResultSet結果集是空的話,queryForObject會拋出異常;如果ResultSet結果集的大小大於1的話,queryForObject也會拋出異常。

查看一下queryForObject源碼:

Spring源碼之JdbcTemplate中的坑,你中招了嗎

queryForObject

其實,queryForObject使用的是一個SingleColumnRowMapper對象,其中,第二個queryForObject方法會調用第一個queryForObject方法,坑就在DataAccessUtils.requiredSingleResult(results)裡面。

看一下DataAccessUtils.requiredSingleResult(results)源碼:

Spring源碼之JdbcTemplate中的坑,你中招了嗎

requiredSingleResult

如圖所示,如果結果集為空,或者結果集的數量大於1,都會拋出異常,導致queryForObject()無法返回期望結果。

重點(敲黑板)

在我們想查找出一個對象時,應該使用query()方法,如果返回結果不為空,那麼取其中的第一個結果就好了。一般不要使用queryForObject方法,queryForObject會要求符合條件的數據庫結果集有且僅有一條記錄,記錄不存在或者記錄數大於1都會拋出異常。

喜歡的可以關注我,每天都有原創高質量文章發出!

Spring源碼之JdbcTemplate中的坑,你中招了嗎

更多文章

  1. 項目中根據相對路徑和絕對路徑獲取文件/資源的方法

  2. JavaEE、Spring源碼之JdbcTemplate分析

  3. Java中最重要的併發編程抽象工具類

  4. Java執行系統命令、外部腳本或外部程序

  5. Java網絡爬蟲工具,OkHttp完全詳細用法

相關推薦

推薦中...