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。