如何在MyBatis中遍历Java列表生成带OR的LIKE条件SQL查询
修正MyBatis查询以生成带OR的LIKE条件
嘿,我明白你的问题啦!你现在遇到的核心问题是条件逻辑的连接符位置错误,而且没把多个OR条件合理包裹,导致MyBatis生成了AND连接的语句,甚至还可能引发逻辑优先级的问题(比如如果不包裹括号,spec_id=50 AND A OR B会被解析成(spec_id=50 AND A) OR B,这大概率不是你想要的逻辑)。
问题根源
你原来的<foreach>里每次都添加AND,然后试图用<trim>替换,但<trim>的位置完全不对,根本没起到调整连接符的作用,所以每个LIKE条件都被AND强行连接了。
修正后的查询语句
我们需要把所有mrch_ordr_id LIKE的条件用括号包裹,内部用OR连接,再和spec_id=50用AND关联,这样逻辑才准确。这里用<trim>来处理括号和多余的连接符:
<select id="getTransactions" parameterType="SearchCriteria" resultMap="transactions" fetchSize="250"> select count(*) from message msg <where> msg.spec_id = 50 <if test="merchantOrderNums != null and merchantOrderNums.size() > 0"> <trim prefix="AND (" suffix=")" suffixOverrides="OR"> <foreach item="item" index="index" collection="merchantOrderNums"> msg.mrch_ordr_id LIKE '%${item}%' OR </foreach> </trim> </if> </where> </select>
代码细节解释
<trim prefix="AND (" suffix=")" suffixOverrides="OR">:prefix="AND (":在整个OR条件块前添加AND (,把OR组和前面的spec_id=50用AND连接,同时开启括号保证逻辑优先级。suffix=")":在条件块末尾添加),闭合括号,避免逻辑混乱。suffixOverrides="OR":自动移除<foreach>最后一个元素后面多余的OR,防止出现语法错误。
<foreach>内部用OR连接:每个LIKE条件之间用OR关联,完全匹配你的需求。- 增加
merchantOrderNums.size() > 0判断:避免列表为空时生成无效的SQL条件片段。
生成的正确SQL示例
当merchantOrderNums包含ABC和123时,会生成你期望的SQL:
select count(*) from message msg WHERE msg.spec_id = 50 AND (msg.mrch_ordr_id LIKE '%ABC%' OR msg.mrch_ordr_id LIKE '%123%');
另外提醒下:使用${item}可能存在SQL注入风险,如果merchantOrderNums的内容来自用户输入,建议改用更安全的#{item}并手动拼接通配符:
msg.mrch_ordr_id LIKE CONCAT('%', #{item}, '%')
内容的提问来源于stack exchange,提问作者Ruchi Gupta
相关产品推荐
相关产品推荐

