MyBatis 3.1执行XPATH SQL查询仅返回一行结果的问题排查
我之前遇到过类似的MyBatis与SQL工具执行结果不一致的问题,结合你描述的场景,大概率是这几个方向的问题,咱们一步步来排查:
排查方向1:数据对象映射问题
这是最常见的原因,尤其是当SQL工具返回多行但MyBatis只返回一行时,重点检查以下几点:
- 检查ResultMap的
<id>标签配置:MyBatis会通过ResultMap里的<id>字段判断对象唯一性,如果你的PIIData对应的ResultMap中,把某个两行数据都相同的字段设为了<id>(比如错误地把email设为id,但两行数据email相同),MyBatis会认为这是同一个对象,最终只保留最后一条。赶紧核对ResultMap里的<id>是不是真正唯一的主键字段。 - 验证自动映射/手动映射的完整性:如果用的是自动映射,检查
PIIData的字段名和SQL返回的列名是否匹配(注意大小写,比如SQL返回ContactId但实体类是contactId,没开驼峰映射的话会导致字段为空,但MyBatis不会丢行;但如果是手动写的ResultMap,有没有漏掉某个能区分两行的列?) - 临时替换返回类型验证:把Mapper接口的返回类型改成
List<Map<String, Object>>,执行查询后看返回的Map数量。如果是2个,那100%是实体类映射的问题;如果还是1个,那就是SQL执行层面的问题。
排查方向2:MyBatis对XPATH SQL的执行差异
有时候MyBatis的参数绑定或版本问题会导致SQL执行逻辑和工具里不一样:
- 打印实际执行的SQL对比:开启MyBatis的日志(在MyBatis配置文件里设置
logImpl为SLF4J或LOG4J),把执行时打印的完整SQL复制到DataGrip里执行,看结果行数是否一致。如果不一致,说明参数替换出了问题(比如emailVal里的特殊字符被转义,影响了XPATH表达式的解析)。 - 检查XPATH表达式的兼容性:比如在SQL Server中,XPATH可能需要指定命名空间,而MyBatis执行时有没有因为参数或语法转义导致命名空间失效?对比工具里的SQL和MyBatis打印的SQL,看XPATH部分有没有差异。
- 考虑MyBatis版本bug:你用的是3.1版本,这是比较老的版本了(当前稳定版是3.5.x),早期版本可能对XML类型的查询结果处理有bug,尝试升级到最新的3.5.x版本,看问题是否解决。
排查方向3:其他容易忽略的点
- 参数传递是否正确:确认代码中传入的
accountIdVal、emailVal和你在SQL工具里测试的参数完全一致,会不会是代码里传错了值导致结果变少? - 是否被拦截器影响:有没有配置分页拦截器、数据权限拦截器之类的插件?会不会是这些插件偷偷修改了查询结果,只返回了一行?
快速排查步骤
- 先开启MyBatis日志,复制执行的SQL到工具里跑,确认结果行数;
- 替换返回类型为
List<Map>,判断是映射还是SQL执行问题; - 核对ResultMap的
<id>配置,确保唯一标识正确; - 尝试升级MyBatis版本到3.5.x。
内容的提问来源于stack exchange,提问作者Dev Gosain
相关产品推荐
相关产品推荐

