一、错误现象
运行批量插入测试时抛出:
org.apache.ibatis.binding.BindingException: Parameter 'carNum' not found. Available parameters are [cars, param1]
并且 SQL 显示为:
insert into t_car car_num,brand,guide_price,produce_time,car_type values (?,?,?,?,?) , (?,?,?,?,?)
二、错误含义
这个错误包含两个问题:
-
参数绑定错误:
Parameter ‘carNum‘ not found— XML 中使用了#{carNum},但 MyBatis 找不到名为carNum的参数。 -
SQL 语法错误:
insert into t_car car_num,brand,...—INSERT语句中表名后面缺少左括号(。
三、根本原因分析
3.1 问题一:参数绑定错误
查看你的 XML 配置,<foreach> 中很可能写成了:
<foreach collection="cars" item="car" separator=",">
(#{carNum}, #{brand}, #{guidePrice}, #{produceTime}, #{carType})
</foreach>
但是:
-
方法参数使用了
@Param("cars"),类型是List<Car> -
遍历时
item="car"代表集合中的每个Car对象 -
访问对象的属性时,必须加上
item前缀:#{car.carNum}、#{car.brand}
错误写法:#{carNum}(MyBatis 会从顶层参数中找名为 carNum 的单独参数,找不到)
正确写法:#{car.carNum}(从当前遍历的 car 对象中取 carNum 属性)
3.2 问题二:SQL 语法错误
SQL 语句:
insert into t_car car_num,brand,guide_price,produce_time,car_type values ...
应该是:
insert into t_car (car_num, brand, guide_price, produce_time, car_type) values ...
表名 t_car 后面缺少左括号 (。
3.3 从日志看具体问题
日志中显示:
Parameter 'carNum' not found. Available parameters are [cars, param1]
这说明 MyBatis 的可用参数只有两个:cars(@Param 注解名)和 param1(默认名)。当你写 #{carNum} 时,MyBatis 会去查找名为 carNum 的顶层参数,但 carNum 既不是 @Param("cars"),也不是 param1,所以找不到。
同时,生成的 SQL 中字段列表缺少括号,这是 XML 中 INSERT 语句本身的问题。
四、解决方案
4.1 修正后的 XML
<insert id="insertMore">
INSERT INTO t_car (car_num, brand, guide_price, produce_time, car_type)
VALUES
<foreach collection="cars" item="car" separator=",">
(#{car.carNum}, #{car.brand}, #{car.guidePrice},
#{car.produceTime}, #{car.carType})
</foreach>
</insert>
4.2 修正点对比
| 错误写法 | 正确写法 | 说明 |
|---|---|---|
insert into t_car car_num
|
INSERT INTO t_car (car_num
|
表名后加 (
|
#{carNum}
|
#{car.carNum}
|
加上 item 前缀
|
#{brand}
|
#{car.brand}
|
加上 item 前缀
|
#{guidePrice}
|
#{car.guidePrice}
|
加上 item 前缀
|
#{produceTime}
|
#{car.produceTime}
|
加上 item 前缀
|
#{carType}
|
#{car.carType}
|
加上 item 前缀
|
4.3 完整示例
Mapper 接口:
public interface CarMapper {
int insertMore(@Param("cars") List<Car> carList);
}
XML 映射:
<insert id="insertMore">
INSERT INTO t_car (car_num, brand, guide_price, produce_time, car_type)
VALUES
<foreach collection="cars" item="car" separator=",">
(#{car.carNum}, #{car.brand}, #{car.guidePrice},
#{car.produceTime}, #{car.carType})
</foreach>
</insert>
测试代码:
@Test
public void test6() {
List<Car> carList = Arrays.asList(
new Car("京A11111", "宝马", 30.0, "2024-01-01", "燃油车"),
new Car("京A22222", "奔驰", 45.0, "2024-01-02", "燃油车")
);
carMapper.insertMore(carList);
sqlSession.commit();
}
五、#{}取值规则详解
在 <foreach> 中,#{} 的取值规则与普通场景不同:
| 写法 | 取值对象 | 说明 |
|---|---|---|
#{carNum}
|
顶层参数(Map 的 Key) |
从方法参数中查找 carNum 这个 Key
|
#{car.carNum}
|
item 对象的属性
|
从当前遍历的 car 对象中取 carNum 属性
|
#{item.carNum}
|
同上 |
如果 item="item",写法为 #{item.carNum}
|
关键:在 <foreach> 内部,当 item 是对象时,必须通过 item.属性名 访问属性;当 item 是基本类型时,直接写 #{item} 即可。
六、常见错误速查表
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
Parameter 'xxx' not found. Available parameters are [cars, param1]
|
未加 item 前缀
|
改为 #{car.xxx}
|
Parameter 'list' not found. Available parameters are [cars, param1]
|
collection 值写错
|
改为 collection="cars"
|
SQL 语法错误 near 'values (?,?,?)'
|
表名后缺少 (
|
加上 (car_num, brand, ...)
|
插入成功但数据为 null
|
字段名写错 | 检查字段名是否匹配数据库列 |
七、排查步骤总结
遇到批量插入错误时,按以下步骤检查:
-
✅ 检查 SQL 语法是否正确(表名后有
(,VALUES后有() -
✅ 检查
<foreach>的collection是否与@Param一致 -
✅ 检查
item是否在#{}中作为前缀使用(如#{item.xxx}) - ✅ 开启 MyBatis 日志,查看生成的完整 SQL
- ✅ 确认实体类属性名与数据库列名对应关系
结语
批量插入是 MyBatis 中最常见的性能优化手段之一,但也是参数绑定最容易出错的地方。
记住两条核心规则:
-
collection的名称必须与@Param注解值或默认名称(list/array)一致。 -
#{}中如果要访问对象的属性,必须加上item前缀(如#{car.xxx})。
掌握这两条规则,批量插入的各种错误都能迎刃而解。
以上就是MyBatis批量插入时Parameter ‘carNum‘ not found错误的解决方法的详细内容,更多关于MyBatis批量插入Parameter not found的资料请关注其它相关文章!













