MyBatis 查詢結果自動封裝為map,出現null而沒有欄位名
阿新 • • 發佈:2020-11-12
date: 2020-11-03 17:14:00
updated: 2020-11-03 17:40:00
MyBatis 查詢結果自動封裝為map,出現null而沒有欄位名
- 問題
select a, b, c from table
>>
a b c
1
// 查詢結果中,第一條資料這三個欄位都是null,沒有值,第二條資料只有a欄位有值,在自動封裝為hashmap返回時的結果如下:
[
null,
{
"a": 1
}
]
- 原因:
org.apache.ibatis.executor.resultset.DefaultResultSetHandler 類下面找到 getRowValue
private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap, String columnPrefix) throws SQLException { final ResultLoaderMap lazyLoader = new ResultLoaderMap(); Object rowValue = createResultObject(rsw, resultMap, lazyLoader, columnPrefix); if (rowValue != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) { final MetaObject metaObject = configuration.newMetaObject(rowValue); boolean foundValues = this.useConstructorMappings; if (shouldApplyAutomaticMappings(resultMap, false)) { foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, columnPrefix) || foundValues; } foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, columnPrefix) || foundValues; foundValues = lazyLoader.size() > 0 || foundValues; rowValue = foundValues || configuration.isReturnInstanceForEmptyRow() ? rowValue : null; } return rowValue; }
在對 rowValue 賦值的時候,會去判斷語句查詢是否有值 或者 configuration.isReturnInstanceForEmptyRow() 這個配置項是否為true,如果前面都是false的話,就置為null,也就是最後返回結果裡null的原因
引數 | 含義 | 有效值 | 預設值 |
---|---|---|---|
callSettersOnNulls | 指定當結果集中值為 null 的時候是否呼叫對映物件的 setter(map 物件時為 put)方法,這在依賴於 Map.keySet() 或 null 值進行初始化時比較有用。注意基本型別(int、boolean 等)是不能設定成 null 的。 | true | |
false |
returnInstanceForEmptyRow | 當返回行的所有列都是空時,MyBatis預設返回 null。 當開啟這個設定時,MyBatis會返回一個空例項。 請注意,它也適用於巢狀的結果集(如集合或關聯)。(新增於 3.4.2) | true | false |
false |
- 解決:
在 mybatis-config.xml 檔案裡新增兩個引數
<configuration>
<settings>
<!-- 指定當結果集中值為 null 的時候是否呼叫對映物件的 setter(map 物件時為 put)方法-->
<setting name="callSettersOnNulls" value="true"/>
<!-- 當返回行的所有列都是空時,MyBatis預設返回 null。 當開啟這個設定時,MyBatis會返回一個空例項。 請注意,它也適用於巢狀的結果集(如集合或關聯)-->
<setting name="returnInstanceForEmptyRow" value="true"/>
</settings>
</configuration>
在 application.properties 裡去指定 mybatis-config.xml 的路徑
mybatis.config-location: mybatis-config.xml
或者在註冊sqlFactory的時候,去指定configLocation
bean.setConfigLocation(new DefaultResourceLoader().getResource("classpath:mybatis-config.xml"));