如何在MyBatis XML查询中为字符串列表参数的每个元素调用UuidToBin函数(基于MariaDB 10.x、Spring Boot 2.x)
解决方案:在MyBatis XML中为列表参数的每个元素调用自定义函数
我明白你的痛点——要把字符串列表里的每个UUID转换成binary类型,就得给每个元素都套上UuidToBin()函数,MyBatis的<foreach>标签刚好能搞定这个事儿。下面直接给你可落地的方案:
1. Mapper接口方法定义
首先在你的Mapper接口里定义对应的方法,接收两个列表参数,记得用@Param注解给参数命名,这样XML里能准确引用:
import java.util.List; import org.apache.ibatis.annotations.Param; public interface ProductOfferingMapper { List<ProductOfferingDto> selectDistinctShopProducts( @Param("idList") List<String> idList, @Param("shopIdList") List<String> shopIdList ); }
(这里假设ProductOfferingDto是你用来接收查询结果的实体类,包含shopId(String类型)、name、state字段)
2. MyBatis XML查询语句
接下来写XML的查询部分,用<foreach>遍历两个列表,每个元素都调用UuidToBin()函数:
<select id="selectDistinctShopProducts" resultType="com.yourpackage.ProductOfferingDto"> SELECT DISTINCT UuidFromBin(po.shop_id) AS shop_id, po.name, po.state FROM product_offering po WHERE <!-- 处理id列表:每个UUID转换为binary --> <if test="idList != null and idList.size() > 0"> po.id IN ( <foreach collection="idList" item="uuid" separator=","> UuidToBin(#{uuid}) </foreach> ) AND </if> <!-- 处理shop_id列表:每个UUID转换为binary --> <if test="shopIdList != null and shopIdList.size() > 0"> po.shop_id IN ( <foreach collection="shopIdList" item="shopUuid" separator=","> UuidToBin(#{shopUuid}) </foreach> ) </if> <!-- 可选:如果两个列表都为空,避免全表扫描,这里可以加个默认条件或者抛出提示 --> <if test="(idList == null or idList.size() == 0) and (shopIdList == null or shopIdList.size() == 0)"> 1 = 0 </if> </select>
关键细节解释
<foreach>标签的用法:collection:对应接口里@Param注解的参数名(比如idList、shopIdList)item:遍历过程中每个元素的别名(比如uuid、shopUuid)separator:元素之间的分隔符,这里用逗号,生成UuidToBin('xxx'), UuidToBin('yyy')这样的格式
- 函数调用与参数绑定:
UuidToBin(#{uuid})里的#{uuid}会被MyBatis安全地替换成列表中的字符串元素,自动处理SQL注入问题 - 空列表处理:加入
<if>判断避免生成IN ()这种无效的SQL语法,同时最后加1=0防止两个列表都为空时触发全表查询
额外提示
你列表里的部分UUID格式有点不规范(比如00000000-0000-3100--0000-00000000有两个连续的连字符),要确保你的UuidToBin()函数能正确处理这种格式,或者在传入参数前先做格式校验和修正,避免数据库函数报错。
内容的提问来源于stack exchange,提问作者Fiyaz Hasan
相关产品推荐
相关产品推荐

