MyBatis设置resultType为LinkedHashMap未保留SQL列顺序如何解决
解决方案
有三种可靠方式可以解决这个问题,按实现成本从低到高排序:
方式一:调整MyBatis全局配置(最低成本,推荐)
MyBatis默认对Map类型的结果集,会优先使用HashMap存储,哪怕你显式指定了resultType为LinkedHashMap,部分旧版本也可能出现未正确实例化的问题。你只需要在mybatis-config.xml的settings节点添加如下配置:
<settings> <!-- 指定Map类型的结果默认使用LinkedHashMap实现,保留查询列顺序 --> <setting name="defaultMapType" value="java.util.LinkedHashMap"/> </settings>
配置完成后,哪怕你把resultType简写为map或者hashmap,返回的结果也会是有序的LinkedHashMap,完全保留SQL中的列顺序。
方式二:自定义ResultHandler(适合不想改全局配置的场景)
如果因为业务限制不能修改全局配置,可以单独给这个查询指定自定义结果处理器,手动把每一行结果封装为LinkedHashMap:
- 先在Mapper接口中定义方法,注意不要写返回值,用ResultHandler接收结果:
void queryCustomSql(Map<String, Object> params, ResultHandler resultHandler);
- 业务层调用的时候自己实现ResultHandler处理结果:
List<LinkedHashMap<String, Object>> resultList = new ArrayList<>(); mapper.queryCustomSql(params, resultContext -> { LinkedHashMap<String, Object> row = (LinkedHashMap<String, Object>) resultContext.getResultObject(); resultList.add(row); });
- Mapper.xml中的resultType还是正常写
java.util.LinkedHashMap即可。
方式三:自定义结果映射(适合列名需要特殊处理的场景)
如果你的查询列有别名或者需要特殊转换,可以直接写ResultMap,明确指定列的顺序,type指定为LinkedHashMap:
<resultMap id="customSqlResultMap" type="java.util.LinkedHashMap"> <!-- 按SQL查询的列顺序依次写result标签,column对应SQL列名,property对应Map的key --> <result column="col1" property="col1"/> <result column="col2" property="col2"/> <!-- 其余63个列依次按顺序添加 --> </resultMap>
然后在查询语句中把resultType替换为resultMap="customSqlResultMap"即可,这种方式的顺序是完全可控的,不会受MyBatis版本影响。
注意事项
- 如果用的是MyBatis-Plus等增强框架,需要确认框架本身的结果处理器是否覆盖了MyBatis的原生配置,部分增强框架会默认修改Map的实现类,额外配置对应的参数即可。
- 不要用
HashMap作为返回类型,HashMap本身的实现就是无序的,JDK8之后虽然会按哈希值排序,但和SQL的查询顺序完全无关。
内容的提问来源于stack exchange,提问作者xuemei qin
相关产品推荐
相关产品推荐

