MyBatis 查詢結果自動封裝為map,出現null而沒有字段名


date: 2020-11-03 17:14:00
updated: 2020-11-03 17:40:00

MyBatis 查詢結果自動封裝為map,出現null而沒有字段名

  1. 問題
select a, b, c from table
>> 
a   b   c

1      
// 查詢結果中,第一條數據這三個字段都是null,沒有值,第二條數據只有a字段有值,在自動封裝為hashmap返回時的結果如下:
[
    null,
    {
        "a": 1
    }
]
  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 false
returnInstanceForEmptyRow 當返回行的所有列都是空時,MyBatis默認返回 null。 當開啟這個設置時,MyBatis會返回一個空實例。 請注意,它也適用於嵌套的結果集(如集合或關聯)。(新增於 3.4.2) true | false false
  1. 解決:

在 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"));


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM