一、基础用法说明
FIND_IN_SET(str, strlist) 函数的作用是:在 strlist(逗号分隔的字符串)中查找 str 的位置,返回值是数字(找到则返回位置,从1开始;没找到返回0)。
结合 MyBatis 的 #{ids} 是为了安全地传入参数,避免 SQL 注入。
二、完整使用示例
1. 场景:根据多个 ID 批量查询数据
假设你有一张 user 表,想通过多个用户 ID(如 1,3,5)查询对应的用户信息,就可以用这个函数。
(1) MyBatis Mapper XML 写法
xml
<!-- UserMapper.xml -->
<select id="selectUserByIds" resultType="com.example.entity.User">
SELECT * FROM user
WHERE FIND_IN_SET(id, #{ids})
</select>
(2) Mapper 接口定义
java
// UserMapper.java
import org.apache.ibatis.annotations.Param;
import java.util.List;
import com.example.entity.User;
public interface UserMapper {
// 注意:参数名要和 XML 中的 #{ids} 对应,建议用 @Param 显式指定
List<User> selectUserByIds(@Param("ids") String ids);
}
(3) 业务层调用
java
// UserService.java
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import com.example.entity.User;
import com.example.mapper.UserMapper;
@Service
public class UserService {
@Resource
private UserMapper userMapper;
public List<User> getUserListByIds() {
// 传入逗号分隔的 ID 字符串
String ids = "1,3,5";
// 调用 Mapper 方法
return userMapper.selectUserByIds(ids);
}
}
2. 关键注意事项
-
参数格式 :
#{ids}接收的必须是逗号分隔的字符串 (如"1,3,5"),不能是 List 集合直接传入(如果是 List,需要先转成字符串)。
示例(List 转字符串):javaList<Integer> idList = Arrays.asList(1,3,5); String ids = String.join(",", idList.stream().map(String::valueOf).toArray(String[]::new)); -
性能提示 :
FIND_IN_SET()无法使用索引,数据量大时性能较差,建议优先用IN (1,3,5)(MyBatis 中可通过<foreach>实现)。 -
返回值逻辑 :
FIND_IN_SET(3, '1,3,5')→ 返回 2(第2个位置)FIND_IN_SET(6, '1,3,5')→ 返回 0(未找到)
三、对比:FIND_IN_SET vs IN(推荐写法)
如果你的参数是 List 集合,更推荐用 <foreach> 拼接 IN,性能更好:
xml
<select id="selectUserByIds" resultType="com.example.entity.User">
SELECT * FROM user
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
对应的接口:
java
List<User> selectUserByIds(@Param("ids") List<Integer> ids);
总结
FIND_IN_SET(id, #{ids})中,#{ids}必须传入逗号分隔的字符串,函数返回匹配的位置(非0则命中);- 该写法无法使用索引,数据量大时优先用 MyBatis 的
<foreach>拼接IN; - 使用时注意参数类型:直接传 List 会报错,需转成字符串(或改用
IN写法)。