项目场景:
今天使用Mybatis进行数据批量插入,因为公司使用的是Spring自带的JPA,所以很久没有使用Mybatis了,在进行批量数据插入的时候报了 Column count doesn't match value count at row 1
dao代码如下:
/**
* @Author: Greyfus
* @Create: 2022-05-30 11:11
* @Version:
* @Description:
*/
package com.seeker.mapper;
import com.seeker.pojo.ActionPlanDomain;
import com.seeker.pojo.BaseInfo;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface BaseInfoMapper {
@Select("SELECT * FROM rtm_baseinfo where vehicleType = 1 AND brandCode = #{brandCode} AND roleType = #{roleType} AND type = #{type}")
List<BaseInfo> findBaseInfoByParameters(@Param(value = "brandCode") String brandCode, @Param(value = "roleType") String roleType, @Param("type") String type);
//批量插入数据
int insertActionPlan(@Param("actionPlanDomains") List<ActionPlanDomain> actionPlanDomains);
}
BaseInfoMapper.xml配置:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.seeker.mapper.BaseInfoMapper">
<insert id="insertActionPlan" parameterType="java.util.List">
INSERT INTO
`action_plan`(`created_time`,`updated_time`,`brand_code`,`tenant_code`,`model_code`,`model_year`,`gvid`,`case_overview`,`guide`,`type`,`level`,`role_type`)
VALUES
<foreach collection="actionPlanDomains" item="actionPlan" open="(" close=")" separator=",">
#{actionPlan.createdTime},#{actionPlan.updatedTime},#{actionPlan.brandCode},#{actionPlan.tenantCode},#{actionPlan.modelCode},#{actionPlan.modelYear},#{actionPlan.gvid},#{actionPlan.caseOverView},#{actionPlan.guide},#{actionPlan.type},#{actionPlan.level},#{actionPlan.roleType}
</foreach>
</insert>
</mapper>
首先我检查了字段个数和参数个数是否匹配,发现是匹配的,此时我在想在参数匹配的情况下为什么还报了Column count doesn't match value count at row 1
这个错误,我的foreach
的open属性和close属性也没有写错。
原因分析:
通过报错信息我发现foreach的open属性和close属性是放在整个执行语句的开始和结尾。
SQL的批量查询的语句格式应该是:
INSET INTO TABLE_NAME(column1,column2,column3,column4)
VALUES
(value1,value2,value3,value4),
(value1,value2,value3,value4),
(value1,value2,value3,value4),
(value1,value2,value3,value4)
然后使用Mybatis的foreach生成的格式却是:
INSET INTO TABLE_NAME(column1,column2,column3,column4)
VALUES
(
value1,value2,value3,value4,
value1,value2,value3,value4,
value1,value2,value3,value4,
value1,value2,value3,value4
)
Mybatis的foreach是在整个循环语句的开头和结尾增加(
和 )
,而并不是每个分隔符后加(
和 )
。
解决方案:
去掉forach中的open和close属性,然后在语句中加入(
和 )
。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.seeker.mapper.BaseInfoMapper">
<insert id="insertActionPlan" parameterType="java.util.List">
INSERT INTO
`action_plan`(`created_time`,`updated_time`,`brand_code`,`tenant_code`,`model_code`,`model_year`,`gvid`,`case_overview`,`guide`,`type`,`level`,`role_type`)
VALUES
<foreach collection="actionPlanDomains" item="actionPlan" separator=",">
(#{actionPlan.createdTime},#{actionPlan.updatedTime},#{actionPlan.brandCode},#{actionPlan.tenantCode},#{actionPlan.modelCode},#{actionPlan.modelYear},#{actionPlan.gvid},#{actionPlan.caseOverView},#{actionPlan.guide},#{actionPlan.type},#{actionPlan.level},#{actionPlan.roleType})
</foreach>
</insert>
</mapper>