Mybatis使用record类作为返回值时,值映射错误问题
问题描述
record类:
/**
* 资产组统计record
*/
public record AssetGroupIdRecord(Long groupId, Integer num) {
}
Mapper方法:
/**
* 根据资产组统计数量
* @param channelId 渠道id
* @return List<AssetGroupIdRecord>
*/
@MapKey("groupId")
Map<Long, AssetGroupIdRecord> selectAssetGroupNum(Long channelId);
sql:
<select id="selectAssetGroupNum" resultType="org.asset.record.AssetGroupIdRecord">
select count(*) as num, GROUP_ID as groupId from asset where channel_id = #{channelId} and deleted_at = 0
and history_flag = 0
group by GROUP_ID
</select>
出现的情况是,groupId和num这两个字段的值互换了
问题解决:
将argNameBasedConstructorAutoMapping参数设置为true即可解决上述问题。
在mybatis配置文件中添加配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="argNameBasedConstructorAutoMapping" value="true"/>
</settings>
</configuration>
源码解析
在DefaultResultSetHandler处理类中,在调用构造函数初始化时会调用以下代码:
private Object applyConstructorAutomapping(ResultSetWrapper rsw, ResultMap resultMap, String columnPrefix,
Class<?> resultType, List<Class<?>> constructorArgTypes, List<Object> constructorArgs, Constructor<?> constructor)
throws SQLException {
boolean foundValues = false;
//根据构造方法中参数名字去映射sql数据
if (configuration.isArgNameBasedConstructorAutoMapping()) {
foundValues = applyArgNameBasedConstructorAutoMapping(rsw, resultMap, columnPrefix, constructorArgTypes,
constructorArgs, constructor, foundValues);
} else {
//根据构造方法中参数的顺序去映射sql数据
foundValues = applyColumnOrderBasedConstructorAutomapping(rsw, constructorArgTypes, constructorArgs, constructor,
foundValues);
}
return foundValues || configuration.isReturnInstanceForEmptyRow()
? objectFactory.create(resultType, constructorArgTypes, constructorArgs) : null;
}
如果根据顺序去映射sql数据,就会出现上述的问题。

浙公网安备 33010602011771号