zl程序教程

您现在的位置是:首页 >  后端

当前栏目

mybatis使用QueryWrapper查询为空的问题,可能是接参的类型为基本变量的数组

mybatis变量数组 查询 类型 基本 可能 为空
2023-09-14 09:07:25 时间

问题来源

今天遇到这样的场景:查询某些服务主体下的所有设备,而某些服务主体的接参类型为int数组,即为int[] serviceSubjectIds。前端发出查询请求,后台断点看到,是有参数值的,如图所示:

在这里插入图片描述

由于代码已作改动,特使用int[] ssIds模拟传参

但结果集始终为空,而项目今天又上线,于是,抓紧去排查问题。

排查思路

  • 首先排除接参为空的问题
  • 根据当前服务主体的参数值,使用原生的SQL语句去数据库查询,查询结果是有设备的,如SQL和下图所示
-- 由于涉及到公司机密,表名以table_name形式命名

SELECT
	virtualId 设备Id,
	no 设备编号
FROM
	table_name 
WHERE
	( isRemoved = 0 AND serviceSubjectId IN ( 79,415 ) )

在这里插入图片描述
故而,排除当前服务主体无设备的问题

  • 排查是否为myBatis生成的SQL语句有问题

    • 第一步,使用postman传参

在这里插入图片描述

  • 第二步,查看返回结果
    在这里插入图片描述
  • 结果为空,预测mybatis生成的SQL语句有问题,打印生成的SQL语句

// 由于涉及到公司机密,表名以table_name形式命名,并不返回这么多字段,

Preparing:   SELECT virtualId,no FROM table_name WHERE (isRemoved = 0 AND serviceSubjectId IN (?)) 
Parameters:  [I@4b4d3788(int[])
Total:       0

从上面的Parameters参数来看,占位符 ? 指示的值是:I@4b4d3788,这明显是一个引用地址,自然查询不到结果,替换占位符,得到SQL语句为

SELECT virtualId,no FROM table_name WHERE (isRemoved = 0 AND serviceSubjectId IN (I@4b4d3788)) 

因而,查询结果肯定为空,即展示的total为0,也就是0条数据

  • 猜测:可能是基本变量的数组[]int接参有问题

于是,使用int的包装类来接参,即Integer[] serviceSubjectIds,依旧使用postman来传参,重新打印mybatis生成的SQL语句。
在这里插入图片描述
这次打印出的mybatis所生成的SQL语句:


// 由于涉及到公司机密,表名以table_name形式命名,并不返回这么多字段,

Preparing:   SELECT virtualId,no FROM table_name WHERE (isRemoved = 0 AND serviceSubjectId IN (?)) 
Parameters:  79(Integer), 415(Integer)
Total:       7

从这个SQL语句看,占位符 ?所指示的值为,79,415,替换占位符,得到SQL语句:

   SELECT virtualId,no FROM table_name WHERE (isRemoved = 0 AND serviceSubjectId IN (79, 415)) 

和原生的SQL语句是一致,自然能得到7条数据,即total为7

因而,mybatis生成的SQL语句没有问题,是我们接参的类型有问题,不应该使用基本变量的数组来接参,而是它们对应的包装类。

总结

  • 遇到问题切勿慌张,预测会有哪几个环节出现了问题,列出出现问题的可能性,然后一步一步演示验证。
  • 在使用mybatis框架的queryWrapper类时,不要用基本变量的数组接参,而是用它们对应的包装类接参,以避免这种问题的出现。