解决后台接口查询返回空结果问题
问题描述
在调用 userService.findByIds(relatedPeopleIds) 方法时,尽管传入的 relatedPeopleIds 集合包含有效ID值(如 Set(2,3)),但查询结果始终为空列表。
错误分析
根本原因:类型不匹配
relatedPeopleIds 是 Set
数据库 sys_user 表的 user_id 字段是数值类型(如 BIGINT)
MyBatis 在进行 IN 查询时,字符串集合与数值字段不匹配导致查询失败
SQL 执行情况:
-- 实际执行的SQL(错误情况)
SELECT * FROM sys_user WHERE user_id IN ('2', '3')
-- 期望执行的SQL(正确情况)
SELECT * FROM sys_user WHERE user_id IN (2, 3)
解决方案
方案1:Java端类型转换(推荐)
Set
.map(ScheduleItem::getLeader)
.map(Long::valueOf) // 将String转为Long
.collect(Collectors.toSet());
List
优点:
类型转换在业务逻辑层显式完成
保持数据库查询的简洁性
适用于大多数数值型ID场景
方案2:SQL端类型转换
修改Mapper XML:
适用场景:
当无法修改Java代码时
数据库兼容性要求较高时
方案3:调整数据库字段类型
如果ID本来就是字符串类型:
验证方案
日志验证:
log.debug("查询ID列表: {}", relatedPeopleIds);
// 输出应显示正确的数值类型:[2, 3] 而不是 ["2", "3"]
SQL日志验证:
检查MyBatis执行的最终SQL语句是否符合预期
最佳实践建议
保持类型一致:
推荐在Java中使用与数据库字段匹配的类型(如 Long 对应 BIGINT)
防御性编程:
// 添加空值检查
Set
.map(ScheduleItem::getLeader)
.filter(Objects::nonNull)
.map(Long::valueOf)
.collect(Collectors.toSet());
单元测试:
@Test
void testFindByIds() {
Set
List
assertEquals(2, users.size());
相关配置检查
确认数据库 id 字段的实际类型
检查 MyBatis 的日志配置是否开启:
logging.level.com.ctedu.mapper=DEBUG
总结
该问题的本质是Java对象类型与数据库类型不匹配。推荐采用方案1在Java端进行显式类型转换,这符合"尽早失败"原则,能在编译期发现类型问题,且保持SQL的简洁高效。

浙公网安备 33010602011771号