1. 程式人生 > 其它 >sql查詢欄位為null,但返回的實體類欄位的值是某個欄位值

sql查詢欄位為null,但返回的實體類欄位的值是某個欄位值

技術標籤:mybatisjavamybatissql

首先說怎麼解決。如果返回的實體類有@Builder註解或者自定義構造方法,那麼就去掉該註解和自定義構造方法。因為構造方法會影響mybatis的賦值。沒有就不用看下面了。
bug描述:我的返回實體類繼承了其他類,本身只有三個屬性。使用sql查詢,其中一個欄位的值應該是null,但結果它的值是其父類的一個欄位值。但如果這個欄位不為null,那麼結果沒問題。單獨執行sql沒問題,就是mybatis執行賦值後出現了問題。

mybatis包下有個DefaultResultSetHandler。我自己返回的是個普通實體類,裡面的屬性也都是基本屬性和String。其賦值時執行方法順序:handleRowValuesForSimpleResultMap->getRowValue->(createResultObject->createResultObject->createByConstructorSignature->createUsingConstructor)->applyAutomaticMappings。兩個createResultObject引數不一樣,括號裡的是巢狀的方法。

大致說下結論:呼叫createUsingConstructor時用的是@Builder生成的構造方法,此時就已經賦錯值了,一開始還在想我沒有定義構造方法,後來看了.class檔案發現了構造方法就這樣發現是@Builder生成的。之後呼叫applyAutomaticMappings我個人感覺是一個糾正賦值將sql欄位和實體類欄位對應。
applyAutomaticMappings程式碼如下:

    List<UnMappedColumnAutoMapping> autoMapping = createAutomaticMappings(rsw, resultMap, metaObject,
columnPrefix); boolean foundValues = false; if (!autoMapping.isEmpty()) { for (UnMappedColumnAutoMapping mapping : autoMapping) { final Object value = mapping.typeHandler.getResult(rsw.getResultSet(), mapping.column); if (value != null) { foundValues = true; }
if (value != null || (configuration.isCallSettersOnNulls() && !mapping.primitive)) { // gcode issue #377, call setter on nulls (value is not 'found') metaObject.setValue(mapping.property, value); } } } return foundValues;

所以如果這個value是null,那麼使用構造方法賦的值就不會被糾正過來,導致了此bug。