解决后台接口查询返回空结果问题

问题描述

在调用 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 relatedPeopleIds = scheduleItems.stream()
.map(ScheduleItem::getLeader)
.map(Long::valueOf) // 将String转为Long
.collect(Collectors.toSet());
List users = userService.findByIds(relatedPeopleIds);

优点:
类型转换在业务逻辑层显式完成

保持数据库查询的简洁性

适用于大多数数值型ID场景

方案2:SQL端类型转换

修改Mapper XML:

适用场景:
当无法修改Java代码时

数据库兼容性要求较高时

方案3:调整数据库字段类型

如果ID本来就是字符串类型:

验证方案
日志验证:

  log.debug("查询ID列表: {}", relatedPeopleIds);

// 输出应显示正确的数值类型:[2, 3] 而不是 ["2", "3"]

SQL日志验证:

检查MyBatis执行的最终SQL语句是否符合预期

最佳实践建议
保持类型一致:

推荐在Java中使用与数据库字段匹配的类型(如 Long 对应 BIGINT)
防御性编程:

  // 添加空值检查

Set relatedPeopleIds = scheduleItems.stream()
.map(ScheduleItem::getLeader)
.filter(Objects::nonNull)
.map(Long::valueOf)
.collect(Collectors.toSet());

单元测试:

  @Test

void testFindByIds() {
Set ids = Set.of(2L, 3L);
List users = userService.findByIds(ids);
assertEquals(2, users.size());

相关配置检查
确认数据库 id 字段的实际类型

检查 MyBatis 的日志配置是否开启:

  logging.level.com.ctedu.mapper=DEBUG

总结

该问题的本质是Java对象类型与数据库类型不匹配。推荐采用方案1在Java端进行显式类型转换,这符合"尽早失败"原则,能在编译期发现类型问题,且保持SQL的简洁高效。

posted @ 2025-07-01 18:26  金色新星  阅读(80)  评论(0)    收藏  举报