MyBatis遍历动态列表匹配数据库记录返回空列表求助
排查MyBatis foreach查询返回空列表的问题
我帮你梳理一下代码里的几个关键问题,这些都可能导致查询返回空列表:
1. Service层的代码错误
首先看你的JSON解析与逻辑判断部分:
- 变量重复定义:你先声明了
List<PaymentCommon.CampaignsRsp> list = null;,后面又写了String list = mapper.readValue(...),这里类型冲突导致之前的list变量根本没被赋值,传入DAO的还是null。应该把String去掉,改成:list = mapper.readValue(jsonStr, new TypeReference<List<PaymentCommon.CampaignsRsp>>(){}); - JSON字符串语法错误:原JSON里第一个对象的
value字段后少了闭合的},正确的JSON格式应该是:[{"name":"first ","value":"1 "},{"name":"second","value":"2"},{"name":"third","value":"3"},{"name":"fourth","value":"4"}] - 判断条件错误:你用
JudgeUtils.isNotEmpty(rsp.getCampaigns())来判断,但实际应该判断解析后的list是否非空(因为要传入DAO的是这个list),所以改成:if(JudgeUtils.isNotEmpty(list)) { listRsp = cmmClmWhitelistingDao.getCampaigns(list); } else { System.out.println("LIST IS EMPTY"); }
2. Mapper XML的SQL语法错误
这是导致查询失败的核心问题:
- foreach标签参数错误:IN子句的正确格式是
IN (值1, 值2, 值3),但你写的open="[{"和close="]}"会生成完全不符合SQL语法的语句。正确的写法应该是:<select id="getCampaigns" resultMap="BaseResultMap" > SELECT campaign.campaign_id, campaign.campaign_name FROM clm_campaign campaign WHERE campaign.campaign_name IN <foreach item="item" collection="campaignList" open="(" separator="," close=")"> #{item.name} </foreach> </select>- 注意
collection的值要和DAO方法的参数名一致:你的DAO方法参数是List<PaymentCommon.CampaignsRsp> campaignList,所以这里应该写campaignList而非list;如果担心参数名识别问题,也可以在DAO参数上加@Param("campaignList")明确指定。
- 注意
- SELECT语句多余逗号:原SQL里
campaign.campaign_name后面多了一个逗号,会直接导致SQL语法错误,去掉即可。
3. 字符串空格匹配问题
你的JSON里name字段带有空格(比如"first "),如果数据库中campaign_name字段的值是first(无空格),会导致匹配失败返回空列表。解决方法二选一:
- 解析JSON时处理空格:在
CampaignsRsp的setName方法中加入trim():public void setName(String name) { this.name = name.trim(); } - 在SQL中用
TRIM函数适配:WHERE TRIM(campaign.campaign_name) IN <foreach item="item" collection="campaignList" open="(" separator="," close=")"> #{item.name} </foreach>
4. DAO方法参数规范(可选优化)
为了避免MyBatis识别参数名出错,建议给DAO方法参数加上@Param注解:
List<CmmClmCampaignDO> getCampaigns(@Param("campaignList") List<PaymentCommon.CampaignsRsp> campaignList);
把这些问题逐一修正后,应该就能正确查询到数据了。
内容的提问来源于stack exchange,提问作者dev77




