MyBatis【问题记录 01】mapper传入array\collection\list类型的参数时报BindingException问题解决

568 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1. 问题说明

这里只贴出核心代码:

// 查询数据
List<StatisticalInfo> statisticalInfoList = null;
// 保存数据
boolean isSuccess = baseComponent.batchInsert(statisticalInfoList);

这里是批量保存数据时使用的SQL:

<insert id="batchInsert" parameterType="com.xxx.StatisticalInfo">
	insert into statistical_info (id, table_name, group_time, total_rows)
	values
	<foreach collection="statisticalInfoList" index="index" item="item" separator=",">
		( #{item.id}, #{item.tableName}, #{item.groupTime}, #{item.totalRows} )
	</foreach>
</insert>

报错信息如下:

nested exception is org.apache.ibatis.binding.BindingException: 
Parameter 'statisticalInfoList' not found. Available parameters are [collection, list]

2. 解决

【方法 :one:】只将【collection="statisticalInfoList"】修改为【collection="list"】即可(不用修改其他任何文件):

<insert id="batchInsert" parameterType="com.xxx.StatisticalInfo">
	insert into statistical_info (id, table_name, group_time, total_rows)
	values
	<foreach collection="list" index="index" item="item" separator=",">
		( #{item.id}, #{item.tableName}, #{item.groupTime}, #{item.totalRows} )
	</foreach>
</insert>

【方法 :two:】只在Mapper接口给参数添加 @Param("statisticalInfoList") 注解(不用修改mapper文件):

public interface BaseMapper {
    /**
     * 批量导入统计结果数据
     *
     * @param statisticalInfoList 查询的统计结果
     * @return 导入成功标志
     */
    boolean batchInsert(@Param("statisticalInfoList") List<StatisticalInfo> statisticalInfoList);
}

mapper文件里的SQL依然是【collection="statisticalInfoList"】:

<insert id="batchInsert" parameterType="com.xxx.StatisticalInfo">
	insert into statistical_info (id, table_name, group_time, total_rows)
	values
	<foreach collection="statisticalInfoList" index="index" item="item" separator=",">
		( #{item.id}, #{item.tableName}, #{item.groupTime}, #{item.totalRows} )
	</foreach>
</insert>

【方法 :three:】不修改接口,将参数封装成map对象(适用于多个参数情况)这里添加了一个 schemaName 参数:

// 将参数封装
HashMap<String, Object> parameter = new HashMap<>(2);
parameter.put("insertList", statisticalInfoList);
parameter.put("schemaName", schemaName);

mapper文件里的SQL参数类型修改【parameterType="map"】collection值修改成map对应的key值【collection="insertList"】:

<insert id="batchInsertStatisticalInfo" parameterType="map">
	insert into ${schemaName}stat_data_source (id, table_name, group_time, total_rows)
	values
	<foreach collection="insertList" index="index" item="item" separator=",">
		( #{item.id}, #{item.tableName}, #{item.groupTime}, #{item.totalRows} )
	</foreach>
</insert>

注意: 如果你传入的参数是List对象,而collection写的却是array【collection="array"】

<insert id="batchInsert" parameterType="com.xxx.StatisticalInfo">
	insert into statistical_info (id, table_name, group_time, total_rows)
	values
	<foreach collection="array" index="index" item="item" separator=",">
		( #{item.id}, #{item.tableName}, #{item.groupTime}, #{item.totalRows} )
	</foreach>
</insert>

将会报如下错误:

nested exception is org.apache.ibatis.binding.BindingException: 
Parameter 'array' not found. Available parameters are [collection, list]

使用时要特别注意。

总结

在mapper接口文件里使用@Param("")注解一下参数是很好的习惯,在编码过程中IDE会验证 mapper 文件里的接收到的参数,更不容易出错。