這篇文章將為大家詳細講解有關如何排除mybatis-plus timestamp返回為null的問題,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
在開發時,為了節約時間,我選擇了mybatis框架來開發,然后又在網上找了一個許多人都推薦的mybatis-plus來作為持久層框架。
于是乎我按照官方的DEMO下了一個springBoot的mybatis-plus版本的DEMO
這個DEMO是基于H2數據庫的,跑了下沒有問題。DEMO是能正常運行的。
然后我將這個工程的代碼快速拷貝的新的一個工程里,并把數據庫由H2換為了MYSQL。但項目跑起來時,出現了如下問題:


查詢出來的結果中對于timestamp類型的字段為空

為了解決這個問題,我決定通過debug斷點觀察下是否查詢是把數據數據查出來了
由于用的mybatis-plus框架來開發,而mybaits-plus框架是基于mybatis框架的,為了看是否把數據查詢出來,直接在ResultSetHandler上把一個dubug就好。在默認情況下,mybatis框架使用的ResultSetHandler為DefaultResultSetHandler,當查詢mybatis查詢完畢后,會通過ResultSetHandler的handleResultSets(Statement stmt)方法對查詢的數據結果集進行封裝

所以將斷點打在handlerResultSets方法上最為合適。
再通過statement -> wrapper ->results -> rowData ->rows觀察發現如下數據:

查詢返回的結果集中rows的記錄數為1,第1個字段的ascii為49,而49是ascii中數字1的值。而第二個字段也有值,說明所對應的timestamp字段是有返回值的,數據庫查詢是沒有問題的。
然而通過mybatis代碼進一步封裝后的數據multipleResults又表示,只查詢到了類型為Int的字段的數據

這么也就是說,問題應該是出在了multipleResults的賦值問題上了
//
// HANDLE RESULT SETS
//
@Override
public List<Object> handleResultSets(Statement stmt) throws SQLException {
ErrorContext.instance().activity("handling results").object(mappedStatement.getId());
final List<Object> multipleResults = new ArrayList<Object>();
int resultSetCount = 0;
ResultSetWrapper rsw = getFirstResultSet(stmt);
List<ResultMap> resultMaps = mappedStatement.getResultMaps();
int resultMapCount = resultMaps.size();
validateResultMapsCount(rsw, resultMapCount);
while (rsw != null && resultMapCount > resultSetCount) {
ResultMap resultMap = resultMaps.get(resultSetCount);
handleResultSet(rsw, resultMap, multipleResults, null);
rsw = getNextResultSet(stmt);
cleanUpAfterHandlingResultSet();
resultSetCount++;
}
String[] resultSets = mappedStatement.getResultSets();
if (resultSets != null) {
while (rsw != null && resultSetCount < resultSets.length) {
ResultMapping parentMapping = nextResultMaps.get(resultSets[resultSetCount]);
if (parentMapping != null) {
String nestedResultMapId = parentMapping.getNestedResultMapId();
ResultMap resultMap = configuration.getResultMap(nestedResultMapId);
handleResultSet(rsw, resultMap, null, parentMapping);
}
rsw = getNextResultSet(stmt);
cleanUpAfterHandlingResultSet();
resultSetCount++;
}
}
return collapseSingleResultList(multipleResults);
}說明問題出在 handleResultSet(rsw, resultMap, multipleResults, null);這句代碼上了
//
// GET VALUE FROM ROW FOR SIMPLE RESULT MAP
//
private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap) throws SQLException {
final ResultLoaderMap lazyLoader = new ResultLoaderMap();
Object rowValue = createResultObject(rsw, resultMap, lazyLoader, null);
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, null) || foundValues;
}
foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, null) || foundValues;
foundValues = lazyLoader.size() > 0 || foundValues;
rowValue = (foundValues || configuration.isReturnInstanceForEmptyRow()) ? rowValue : null;
}
return rowValue;
}private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
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;
}
在獲取這個查詢的的返回字段時,只獲取出來兩個,即int類型和varchar類型的.
private List<UnMappedColumnAutoMapping> createAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
final String mapKey = resultMap.getId() + ":" + columnPrefix;
List<UnMappedColumnAutoMapping> autoMapping = autoMappingsCache.get(mapKey);
if (autoMapping == null) {
autoMapping = new ArrayList<UnMappedColumnAutoMapping>();
final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
for (String columnName : unmappedColumnNames) {
String propertyName = columnName;
if (columnPrefix != null && !columnPrefix.isEmpty()) {
// When columnPrefix is specified,
// ignore columns without the prefix.
if (columnName.toUpperCase(Locale.ENGLISH).startsWith(columnPrefix)) {
propertyName = columnName.substring(columnPrefix.length());
} else {
continue;
}
}
final String property = metaObject.findProperty(propertyName, configuration.isMapUnderscoreToCamelCase());
if (property != null && metaObject.hasSetter(property)) {
if (resultMap.getMappedProperties().contains(property)) {
continue;
}
final Class<?> propertyType = metaObject.getSetterType(property);
if (typeHandlerRegistry.hasTypeHandler(propertyType, rsw.getJdbcType(columnName))) {
final TypeHandler<?> typeHandler = rsw.getTypeHandler(propertyType, columnName);
autoMapping.add(new UnMappedColumnAutoMapping(columnName, property, typeHandler, propertyType.isPrimitive()));
} else {
configuration.getAutoMappingUnknownColumnBehavior()
.doAction(mappedStatement, columnName, property, propertyType);
}
} else {
configuration.getAutoMappingUnknownColumnBehavior()
.doAction(mappedStatement, columnName, (property != null) ? property : propertyName, null);
}
}
autoMappingsCache.put(mapKey, autoMapping);
}
return autoMapping;
}final String property = metaObject.findProperty(propertyName, configuration.isMapUnderscoreToCamelCase());
才知道問題所在了, configuration.isMapUnderscoreToCamelCase()的值為true,即開啟了駝峰命令。
所以查找字段時就找不到。 把之前的類似crt_time改為crtTime后,就可以了! 沒想到這么一個小錯誤,讓我糾結了這么久!還好能跟蹤源碼!
通過這次的問題排查,讓我明白了一個道理: 如果不知道某個框架原理的情況下,不要隨便填寫它的配置信息。在享受到框架的便捷性的同時,最好也得要明白它的原理,這樣當出現問題時,才好快速定位。
關于“如何排除mybatis-plus timestamp返回為null的問題”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。