一、错误现象

运行批量插入测试时抛出:

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 (?,?,?,?,?) , (?,?,?,?,?)

二、错误含义

这个错误包含两个问题:

  1. 参数绑定错误Parameter ‘carNum‘ not found — XML 中使用了 #{carNum},但 MyBatis 找不到名为 carNum 的参数。
  2. 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 字段名写错 检查字段名是否匹配数据库列

七、排查步骤总结

遇到批量插入错误时,按以下步骤检查:

  1. ✅ 检查 SQL 语法是否正确(表名后有 (VALUES 后有 (
  2. ✅ 检查 <foreach>collection 是否与 @Param 一致
  3. ✅ 检查 item 是否在 #{} 中作为前缀使用(如 #{item.xxx}
  4. ✅ 开启 MyBatis 日志,查看生成的完整 SQL
  5. ✅ 确认实体类属性名与数据库列名对应关系

结语

批量插入是 MyBatis 中最常见的性能优化手段之一,但也是参数绑定最容易出错的地方。

记住两条核心规则:

  1. collection 的名称必须与 @Param 注解值或默认名称(list/array)一致。
  2. #{} 中如果要访问对象的属性,必须加上 item 前缀(如 #{car.xxx})。

掌握这两条规则,批量插入的各种错误都能迎刃而解。

以上就是MyBatis批量插入时Parameter ‘carNum‘ not found错误的解决方法的详细内容,更多关于MyBatis批量插入Parameter not found的资料请关注其它相关文章!

觉得上面的内容有用吗?快来点个赞吧!

点赞() 我要打赏

温馨提示 : 本站内容来自会员投稿以及互联网,所有源码及教程均为作者总结编辑,请大家在使用过程中提前做好备份,以免发生无法预知的错误,源码类教程请勿直接用于生产环境!

 可能感兴趣的文章