MyBatis 批量插入时 Parameter ‘carNum‘ not found 错误详解

MyBatis 批量插入时 Parameter 'carNum' not found 错误详解

一、错误现象

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

复制代码
org.apache.ibatis.binding.BindingException: Parameter 'carNum' not found. 
Available parameters are [cars, param1]

并且 SQL 显示为:

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> 中很可能写成了:

xml 复制代码
<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 语句:

sql 复制代码
insert into t_car car_num,brand,guide_price,produce_time,car_type values ...

应该是:

sql 复制代码
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

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 接口:

java 复制代码
public interface CarMapper {
    int insertMore(@Param("cars") List<Car> carList);
}

XML 映射:

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>

测试代码:

java 复制代码
@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})。

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

相关推荐
代码什么用3 小时前
在WEB中的应用
mybatis
牧瀬クリスだ4 小时前
Mybatis-Plus:让CRUD快如闪电
java·spring boot·spring·tomcat·mybatis·yml
九皇叔叔17 小时前
【09】SpringBoot4 MyBatisPlus 增删改查(CRUD)
java·mybatis·mybatisplus
景熙552319 小时前
JDBC 详解:从原理到实战(含完整可运行 Demo)
java·spring·tomcat·mybatis·jdbc
程序猿乐锅20 小时前
一文讲透缓存穿透、击穿和雪崩
java·redis·spring·缓存·mybatis
程序猿乐锅1 天前
【黑马点评 | 第九篇】秒杀优化-异步实现
java·spring boot·redis·后端·spring·中间件·mybatis
大漠孤烟s1 天前
7.mybatisplus学习-条件构造器、插件、通用枚举、多数据源环境、MybatisX
mybatis
ee又momo1 天前
MyBatis-Plus 用了就回不去,这些功能真香
mybatis
大漠孤烟s8 天前
4.Mybatis学习-动态sql、缓存、逆向工程
mybatis
毕业设计7039 天前
(免费领源码) SpringBoot 游戏交易平台17600-java、PHP、python、C#、小程序、大数据、单片机、网络工程等)
java·spring boot·mysql·决策树·mybatis·idea·推荐算法