mybatis的标签需规范使用:collection属性须与@param命名一致;空集合时用配合1=2避免语法错误;in元素超1000应分批查询;参数类型必须与数据库字段严格匹配,禁用'#{id}'防止sql注入。

MyBatis 的 <foreach></foreach> 标签是处理集合参数、生成动态 SQL(尤其是 IN 查询)的核心工具。用得好,能避免 N+1 查询、减少数据库交互次数;用得不好,可能触发 SQL 注入、空集合报错或性能下降。关键在于写法规范、边界控制和类型适配。
明确 collection 属性来源:别写错参数名
MyBatis 会将传入的参数封装为一个 Map。当方法接收单个集合参数(如 List<long> ids</long>)时,collection 值默认为 "list";若参数被 @Param("ids") 显式命名,则 collection 必须写成 "ids"。常见错误是硬写 collection="list" 却用了 @Param,导致遍历失败。
建议统一使用 @Param 显式命名,提升可读性与健壮性:
public List<user> selectByIds(@Param("ids") List<long> ids);</long></user>对应 XML 中写法:
<select id="selectByIds" resulttype="User">
SELECT * FROM user WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach></select>安全处理空集合:避免 SQL 语法错误
当传入空集合时,上述 SQL 会变成 WHERE id IN (),直接报错。需配合 <if></if> 判断兜底:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 返回空结果集:加条件拦截,让 SQL 不执行
- 改用
1=2等恒假条件,保持 SQL 合法
推荐写法:
<select id="selectByIds" resulttype="User">
SELECT * FROM user
<where><if test="ids != null and !ids.isEmpty()">
id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach></if><if test="ids == null or ids.isEmpty()">
1 = 2
</if></where></select>优化 IN 元素数量:防止超长 SQL 或参数过多
MySQL 默认 max_allowed_packet 限制单条 SQL 长度,Oracle 对绑定变量数有限制(如 1000 个)。若集合过大(如 > 1000 项),应分批查询:
- Java 层按每 500~999 个元素拆分 List,循环调用 Mapper
- 或在 XML 中用
<bind></bind>计算批次,但复杂度高,不推荐 - 对超大数据量场景,优先考虑临时表或中间表替代 IN
示例分批逻辑(Java):
List<list>> batches = Lists.partition(ids, 999);
List<user> result = new ArrayList();
for (List<long> batch : batches) {
result.addAll(mapper.selectByIds(batch));
}</long></user></list>注意参数类型与 SQL 类型匹配
#{id} 是预编译占位符,类型由 Java 对象决定。若 ids 是 List<string></string>,且数据库字段是数字类型(如 BIGINT),可能因隐式转换失败或索引失效。务必保证类型一致:
- 数值 ID → 用
Long或Integer集合 - 字符串主键(如 UUID)→ 字段和参数都用
String,SQL 中无需额外引号 - 避免混用基本类型与包装类,防止
null导致空指针
不推荐写 '#{id}' —— 这会绕过预编译,有 SQL 注入风险,且类型校验失效。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










