1. 程式人生 > >Spring Druid 使用JdbcTemplate的BeanPropertyRowMapper只有第一行的第一列對映成功,後面都為null

Spring Druid 使用JdbcTemplate的BeanPropertyRowMapper只有第一行的第一列對映成功,後面都為null

在使用Spring的JdbcTemplate進行查詢時使用了BeanPropertyRowMapper來轉化ResultSet到POJO,第一行的Id列有值外,其它都沒有值,為null,而資料庫是有值的。

環境:

sun jdk 1.8

Spring 4.3.9.RELEASE

MariaDb  10.2.12

org.mariadb.jdbc 2.1.0

在用JdbcTemplate.query()時返回資料異常。

斷點除錯發現在

public T mapRow(ResultSet rs, int rowNumber) throws SQLException {

...

Object value = this.getColumnValue(rs, index, pd);//取值老是為空,只有第一次id能正確取到值

...

JdbcUtils.getResultSetValue(rs, index, pd.getPropertyType());

...

return rs.wasNull() ? null : value;

JdbcUtils的rs.wasNull在第二行的Id取值時總是true,表示在sql查詢裡是null的,但其實後面的value是有值的.

以為是Druid連線池的問題,Spring版本,Connector版本等等,更換版本,無效。

最後因為MariaDb不是相容Mysql麼?用用Mysql的connector試試,結果就真提示錯誤資訊了:

SQLException: Value '0000-00-00' can not be represented as java.sql.Date

原來我的最後一列在資料庫中是NULL,在對映時預設為‘0000-00-00’了,這是一個無效的sql.Date,然後在下一行進行讀取時不知為何雖然讀取出了值但是rs.wasNull卻變成了true了,然後搜尋解決方案也很簡單:

在連線地址加上zeroDateTimeBehavior=convertToNull即可,如:
database.url=jdbc:mysql://127.0.0.1:3306/gps?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull

這樣就可以了。

但是比較納悶的是:

按jdk的文件所說

```

wasNull

boolean wasNull()
                throws SQLException

報告最後一個讀取的列是否具有值 SQL NULL。注意,必須首先對列呼叫一個獲取方法嘗試讀取其值,然後呼叫 wasNull 方法檢視讀取的值是否為 SQL NULL

返回:

如果最後一個讀取的列值為 SQL NULL,則返回 true;否則返回 false

丟擲:

- 如果發生資料庫訪問錯誤或在已關閉的結果集上呼叫此方法

```

那麼JdbcUtils在獲取Id的值時已經執行了rs.getInt(index),為何wasNull還是沒有正確返回false而被上一條記錄的日期為null給影響到了?看來主要還是在mariaDb的Connector。